from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django_redis import get_redis_connection
from random import randint
import requests, jwt, json, datetime, hashlib, re, time, xlrd, random, pymysql
from django.utils import timezone
from django.conf import settings
from rest_framework.viewsets import ModelViewSet
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from django.db import transaction
from django.db.models import Q, F, Func

from managers.serializers import *
from equity_mall.utils.common_msg import common_msg
from equity_mall.utils.WXBizDataCrypt import WXBizDataCrypt
from equity_mall.utils.utils import get_level_list, random_str, ryx_settle_order, ryx_profitsharing_order, get_sign
from equity_mall.utils.pages import MyPage
from managers.filters import *
from equity_mall.utils.sync_img_to_local import sync_img_to_local, make_qrcode, make_qrcode2
from equity_mall.utils.qiniu_storage import pic_upload
from managers.tasks import detection_activity_qrcode, detection_cash_activity_qrcode
from merchants.utils import query_merinid, searchmerchantmsg
from equity_mall.celery import celery_app
from equity_mall.utils.utils import mmpaymkttransfers


class SmsCodeView(APIView):

    permission_classes = ()

    def get(self, request, mobile):
        user = User.objects.filter(mobile=mobile, is_active=1, level_id__isnull=False)
        if not user:
            return Response({'error': '该手机号码尚未注册!'}, status=status.HTTP_404_NOT_FOUND)
        redis_conn = get_redis_connection("verify_code")
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            return Response({'error': '发送短信过于频繁!'}, status=status.HTTP_400_BAD_REQUEST)
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, 300, sms_code)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        pl.execute()
        content = f'【微邮付】登录验证码为：{sms_code}，若非本人操作，请忽略。'
        result = common_msg(mobile, content)
        return Response({"errmsg": "发送短信验证码成功"}, status=status.HTTP_200_OK)


class UserLoginView(APIView):

    permission_classes = ()

    def post(self, request):
        code = self.request.data.get('code', None)
        encryptedData = self.request.data.get('encryptedData', None)
        iv = self.request.data.get('iv', None)
        mobile = self.request.data.get('mobile', None)
        sms_code = self.request.data.get('sms_code', None)
        if str(mobile) in ['13800000000', ] and str(sms_code) == str('123456'):
            user = User.objects.get(mobile=mobile)
            dic = {
                'exp': timezone.now() + datetime.timedelta(days=30),
                'iat': timezone.now(),
                'iss': 'manager',
                'data': {
                    'mobile_phone': mobile,
                    'id': user.id,
                    'username': user.username,
                    'nickname': user.nickname
                },
            }
            jwt_token = jwt.encode(dic, settings.MANAGER_SECRET_KEY, algorithm='HS256')
            return Response({'username': user.username, 'user_id': user.id, 'token': jwt_token, 'mobile': user.mobile}, status=status.HTTP_200_OK)
        if not all([code, encryptedData, iv]) and not all([mobile, sms_code]):
            return Response({'error': '缺少必传参数!'}, status=status.HTTP_400_BAD_REQUEST)
        if sms_code:
            try:
                user = User.objects.get(mobile=mobile)
            except:
                return Response({'error': '该手机号码不属于有效用户!'}, status=status.HTTP_400_BAD_REQUEST)
            redis_conn = get_redis_connection("verify_code")
            sms_code_server = redis_conn.get("sms_%s" % mobile)
            black_mobile_server = redis_conn.get("black_%s" % mobile)
            if black_mobile_server:
                black_mobile_server = int(black_mobile_server.decode())
                if black_mobile_server == 5:
                    return Response({'error': "当前账号已被冻结"}, status=status.HTTP_400_BAD_REQUEST)
            else:
                black_mobile_server = 0
            if sms_code_server is None:
                return Response({'error': "短信验证码失效"}, status=status.HTTP_400_BAD_REQUEST)
            sms_code_server = sms_code_server.decode()
            if sms_code_server != str(sms_code):
                black_mobile_server += 1
                redis_conn.setex("black_%s" % mobile, 86400, str(black_mobile_server))
                return Response({'error': "输入验证码有误"}, status=status.HTTP_400_BAD_REQUEST)
            redis_conn.delete("sms_%s" % mobile)
            redis_conn.delete("black_%s" % mobile)
        else:
            url = f'https://api.weixin.qq.com/sns/jscode2session?appid={settings.MANAGER_APP_ID}&secret={settings.MANAGER_APP_SECRET}&js_code={code}&grant_type=authorization_code'
            response = requests.get(url)
            data_dict = json.loads(response.content)
            if 'errcode' in data_dict:
                return Response({'error': str(data_dict['errcode']) + '错误,请联系管理员!'}, status=status.HTTP_400_BAD_REQUEST)
            session_key = data_dict['session_key']
            openid = data_dict['openid']
            pc = WXBizDataCrypt(settings.MANAGER_APP_ID, session_key)
            try:
                mobile = pc.decrypt(encryptedData, iv)['phoneNumber']
            except Exception as e:
                logging.error(e)
                print(e)
                return Response({'error': '获取手机号错误,请重新登录!'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                user = User.objects.get(mobile=mobile, level_id__isnull=False, is_active=1)
            except:
                return Response({'error': '该手机号码不属于有效用户!'}, status=status.HTTP_400_BAD_REQUEST)
            if not user.openid:
                user.openid = openid
                user.save()
        if not user.is_active or not user.level_id or user.role_id in [4, 5]:
            return Response({'error': '用户尚未激活!'}, status=status.HTTP_400_BAD_REQUEST)
        dic = {
            'exp': timezone.now() + datetime.timedelta(days=30),
            'iat': timezone.now(),
            'iss': 'manager',
            'data': {
                'mobile_phone': mobile,
                'id': user.id,
                'username': user.username,
                'nickname': user.nickname
            },
        }
        jwt_token = jwt.encode(dic, settings.MANAGER_SECRET_KEY, algorithm='HS256')
        return Response({'username': user.username, 'user_id': user.id, 'token': jwt_token, 'mobile': user.mobile}, status=status.HTTP_200_OK)


class UserModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('username', 'mobile', 'nickname')
    filter_class = ManagerUserFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return ManagerUserListModelSerializer
        else:
            return ManagerUserRetrieveModelSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = User.objects.all().order_by('-create_time')
        elif level.level == 1:
            queryset = User.objects.filter(level__prov_id=level.id).order_by('-create_time')
        elif level.level == 2:
            queryset = User.objects.filter(level__city_id=level.id).order_by('-create_time')
        elif level.level == 3:
            queryset = User.objects.filter(level__district_id=level.id).order_by('-create_time')
        else:
            queryset = User.objects.filter(level__branch_id=level.id).order_by('-create_time')
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['is_active_count'] = str(queryset.filter(is_active=1).count())
        self.request.data['not_is_active_count'] = str(queryset.filter(is_active=0).count())
        self.request.data['active_count'] = str(queryset.count())
        return queryset

    def info(self, request):
        user = self.request.iser
        return Response(UserInfoModelSerializer(user).data, status=status.HTTP_200_OK)

    def synchronous_info(self, request):
        user = self.request.iser
        username = self.request.data.get('username', None)
        avatar = self.request.data.get('avatar', None)
        # print(avatar)
        if username:
            user.username = username
        if avatar:
            user.avatar = avatar
        user.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        level = user.level
        mobile = self.request.data.get('mobile', None)
        username = self.request.data.get('username', None)
        role_id = self.request.data.get('role_id', 3)
        is_active = self.request.data.get('is_active', 1)
        if not all([mobile, username, role_id, is_active]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(role_id) not in ['2', '3']:
            return Response({'error': '无效角色id'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_active) not in ['0', '1']:
            return Response({'error': '状态参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        user_data = {}
        user_data['mobile'] = mobile
        user_data['username'] = username
        user_data['nickname'] = username
        user_data['role_id'] = role_id
        user_data['is_active'] = is_active
        user_data['level_id'] = level.id
        user_data['create_time'] = datetime.datetime.now()
        user_data['create_user_id'] = user.id
        try:
            user, create = User.objects.get_or_create(defaults=user_data, mobile=mobile)
            if create:
                return Response({'success': '添加成功', 'id': user.id}, status=status.HTTP_200_OK)
            else:
                if not user.level_id:
                    user.level_id = level.id
                    user.save()
                return Response({'success': f'该手机号码已注册，请引导客户经理{user.username}使用手机号码{user.mobile}登录【赋能惠礼】微信小程序', 'id': user.id}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        user = self.request.iser
        level = user.level
        mobile = self.request.data.get('mobile', None)
        username = self.request.data.get('username', None)
        role_id = self.request.data.get('role_id', None)
        is_active = self.request.data.get('is_active', '')
        level_id = self.request.data.get('level_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id not in level_list:
                    return Response({'error': '无效机构id'}, status=status.HTTP_400_BAD_REQUEST)
            except:
                return Response({'error': '无效机构id'}, status=status.HTTP_400_BAD_REQUEST)
            instance.level_id = level_id
        if str(is_active):
            if str(is_active) not in ['0', '1']:
                return Response({'error': '状态参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            instance.is_active = is_active
        if role_id:
            if str(role_id) not in ['2', '3']:
                return Response({'error': '无效角色id'}, status=status.HTTP_400_BAD_REQUEST)
            instance.role_id = role_id
        if mobile and mobile != instance.mobile:
            if not re.match(r'^1[3-9]\d{9}$', mobile):
                return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
            user = User.objects.filter(mobile=mobile)
            if user:
                return Response({"error": "手机号码重复"}, status=status.HTTP_400_BAD_REQUEST)
            instance.mobile = mobile
        if username:
            instance.username = username
            instance.nickname = username
        instance.save()
        return Response({"success": "修改成功"}, status=status.HTTP_200_OK)

    def authorization_mobile(self, request):
        code = self.request.data.get('code', None)
        encryptedData = self.request.data.get('encryptedData', None)
        iv = self.request.data.get('iv', None)
        if not all([code, encryptedData, iv]):
            return Response({'error': '缺少必传参数!'}, status=status.HTTP_400_BAD_REQUEST)
        url = f'https://api.weixin.qq.com/sns/jscode2session?appid={settings.MANAGER_APP_ID}&secret={settings.MANAGER_APP_SECRET}&js_code={code}&grant_type=authorization_code'
        response = requests.get(url)
        data_dict = json.loads(response.content)
        if 'errcode' in data_dict:
            return Response({'error': str(data_dict['errcode']) + '错误,请联系管理员!'}, status=status.HTTP_400_BAD_REQUEST)
        session_key = data_dict['session_key']
        openid = data_dict['openid']
        pc = WXBizDataCrypt(settings.MANAGER_APP_ID, session_key)
        try:
            mobile = pc.decrypt(encryptedData, iv)['phoneNumber']
            return Response({'success': '获取成功', 'mobile': mobile}, status=status.HTTP_200_OK)
        except Exception as e:
            logging.error(e)
            print(e)
            return Response({'error': '获取手机号错误,请重新登录!'}, status=status.HTTP_400_BAD_REQUEST)

    def invite_manager(self, request):
        user_id = self.request.data.get('user_id', None)
        mobile = self.request.data.get('mobile', None)
        username = self.request.data.get('username', None)
        if not all([mobile, username, user_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        try:
            invite_manager = User.objects.get(identify=user_id)
        except:
            return Response({'error': '无效邀请二维码'}, status=status.HTTP_400_BAD_REQUEST)
        level_id = invite_manager.level_id
        role_id = 3
        is_active = 0
        user_data = {}
        user_data['mobile'] = mobile
        user_data['username'] = username
        user_data['nickname'] = username
        user_data['role_id'] = role_id
        user_data['is_active'] = is_active
        user_data['level_id'] = level_id
        user_data['create_time'] = datetime.datetime.now()
        user_data['create_user_id'] = invite_manager.id
        try:
            user, create = User.objects.get_or_create(defaults=user_data, mobile=mobile)
            if create:
                return Response({'success': '添加成功,请等待机构管理员审核'}, status=status.HTTP_200_OK)
            else:
                return Response({'error': '重复添加'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def manager_info(self, request):
        user_id = self.request.query_params.get('user_id', None)
        if not user_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            invite_manager = User.objects.get(identify=user_id)
        except:
            return Response({'error': '无效邀请二维码'}, status=status.HTTP_400_BAD_REQUEST)
        data = {}
        data['level_name'] = invite_manager.level.name
        data['username'] = invite_manager.username
        data['mobile'] = invite_manager.mobile
        return Response(data, status=status.HTTP_200_OK)

    def update_signature(self, request):
        user = self.request.iser
        # signature = self.request.data.get('signature', None)
        signature = self.request.FILES.get('img', None)
        if not signature:
            return Response({'error': '缺少签名'}, status=status.HTTP_400_BAD_REQUEST)
        if not all([signature]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if signature.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = signature.read()
        signature.seek(0)
        mid_img = pic_upload(img_str)
        user.is_agreement = 1
        user.signature = mid_img
        user.sign_time = datetime.datetime.now()
        user.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class MerchantModelViewSet(ModelViewSet):
    '''商户模型类'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'wyfMerchantID', 'managerName', 'managermobile')

    def get_queryset(self):
        if self.action == 'create':
            queryset = Merchant.objects.all()
        else:
            user = self.request.iser
            level = user.level
            level_id = self.request.query_params.get('level', None)
            is_mall = self.request.query_params.get('is_mall', None)
            if level_id:
                try:
                    level_list = get_level_list(level)
                    level_id = int(level_id)
                    if level_id in level_list:
                        level = Level.objects.filter(id=level_id).first()
                except:
                    pass
            # if level.level == 0:
            #     queryset = Merchant.objects.all().order_by('-create_time')
            # elif level.level == 1:
            #     queryset = Merchant.objects.filter(merchantenter__level__prov_id=level.id).order_by('-create_time')
            # elif level.level == 2:
            #     queryset = Merchant.objects.filter(merchantenter__level__city_id=level.id).order_by('-create_time')
            # elif level.level == 3:
            #     queryset = Merchant.objects.filter(merchantenter__level__district_id=level.id).order_by('-create_time')
            # else:
            #     queryset = Merchant.objects.filter(merchantenter__level__branch_id=level.id).order_by('-create_time')
            queryset = Merchant.objects.filter(merchantenter__level_id=level.id).order_by('-create_time')
            if is_mall:
                if '0' not in is_mall:
                    queryset = queryset.exclude(channel_id=2)
                if '1' not in is_mall:
                    queryset = queryset.exclude(Q(is_mall=0) & Q(subject_type__in=[2, 3]))
                if '2' not in is_mall:
                    queryset = queryset.exclude(is_mall=1)
                if '3' not in is_mall:
                    queryset = queryset.exclude(applyment_state__in=[1, 5])
                if '4' not in is_mall:
                    queryset = queryset.exclude(applyment_state=4)
                if '5' not in is_mall:
                    queryset = queryset.exclude(verify_state=1)
                if '6' not in is_mall:
                    queryset = queryset.exclude(applyment_state=3, verify_state=3)
                if '7' not in is_mall:
                    queryset = queryset.exclude(is_mall=2)
                if '8' not in is_mall:
                    queryset = queryset.exclude(is_mall=3)
        return queryset

    def get_serializer_context(self):
        user = self.request.iser
        return {'user': user}

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantListModelSerializer
        else:
            path = self.request.path
            if 'merchantinfo' in path:
                return MerchantInfoRetrieveModelSerializer
            else:
                return MerchantRetrieveModelSerializer

    def check_merchant(self, request):
        user = self.request.iser
        business_no = self.request.data.get('business_no', None)
        if not business_no:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        business_no = str(business_no).replace(' ', '')
        if not business_no.isdigit() and len(business_no) != 10:
            return Response({'error': '请输入10位纯数字微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
        md5 = hashlib.md5()  # 使用MD5加密模式
        md5.update(str(business_no).encode('utf-8'))  # 将参数字符串传入
        sign = md5.hexdigest()  # 完成加密并转为大写
        url = 'https://manage.gdwxyf.com/internal/searchmerchantbyshopids.do'
        body = {
            'account': 'gdyouzheng',
            'shopId': sign
        }
        reaponse = requests.post(url=url, data=body)
        try:
            reaponse = reaponse.json()
        except:
            return Response({'error': '系统繁忙,请重新操作'}, status=status.HTTP_400_BAD_REQUEST)
        if 'wx_channel_merchant_id' not in reaponse:
            return Response({'error': '商户号有误,请检查重新操作'}, status=status.HTTP_400_BAD_REQUEST)
        if reaponse['wx_channel_merchant_id'] == '':
            return Response({'error': '获取商户信息失败，请确认该商户是否审核成功。'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = Merchant.objects.filter(wyfMerchantID=business_no).first()
        if merchant:
            merchantchannel_data = {
                'merchant_id': merchant.id
            }
            if reaponse['allchannelJson']['channel_ruiyinxin']:
                if reaponse['allchannelJson']['channel_ruiyinxin']['status'] == 1:
                    merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                    merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                    merchantchannel_data['channel_id'] = 2
                    merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_3']
                    MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
            if reaponse['allchannelJson']['channel_sxf_tq']:
                if reaponse['allchannelJson']['channel_sxf_tq']['status'] == 1:
                    merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_4'] if 'merchant_other_4' in reaponse['allchannelJson']['channel_sxf_tq'] else ''
                    merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_no']
                    merchantchannel_data['channel_id'] = 3
                    merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_3']
                    MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
            if reaponse['channel_mch_id'] == '227823797':
                try:
                    channel_url = 'https://manage.gdwxyf.com/internal/searchmerchantchannelmsg.do'
                    channel_body = {"account": "gdyouzheng", "shopId": sign}
                    channel_response = requests.post(url=channel_url, data=channel_body)
                    channel_result = channel_response.json()
                    merchantchannel_data['smid'] = channel_result['alipaychannelJson']['merchant_other_4'] if 'merchant_other_4' in channel_result['alipaychannelJson'] else ''
                    merchantchannel_data['channel_mchid'] = channel_result['alipaychannelJson']['upMerchantNo']
                    merchantchannel_data['channel_id'] = 15
                    merchantchannel_data['sub_mchid'] = channel_result['wxchannelJson']['merchant_other_3']
                    MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                except:
                    pass
        else:
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    merchant_data = {}
                    channel_mch_id = reaponse['channel_mch_id']
                    channel = Channel.objects.filter(mchid=channel_mch_id).first()
                    if channel:
                        merchant_data['channel_id'] = channel.id
                    merchant_data['name'] = reaponse['shopName']
                    merchant_data['short_name'] = reaponse['shopNickname']
                    merchant_data['wyfMerchantID'] = business_no
                    merchant_data['ruiyinxinMerchantID'] = sign
                    merchant_data['create_time'] = datetime.datetime.now()
                    if reaponse['businessType'] == '1':
                        merchant_data['subject_type'] = 3
                    elif reaponse['businessType'] == '2':
                        merchant_data['subject_type'] = 2
                    elif reaponse['businessType'] == '3':
                        merchant_data['subject_type'] = 1
                    else:
                        merchant_data['subject_type'] = 4
                    level = Level.objects.filter(acceptId=reaponse['accept_id']).first()
                    if level:
                        merchant_data['level_id'] = level.id
                    merchantuser, create = MerchantUser.objects.get_or_create(mobile=reaponse['phone'], defaults={"mobile": reaponse['phone'], 'level_id': level.id if level else None})
                    merchant_data['merchantuser_id'] = merchantuser.id
                    merchant_data['account_name'] = reaponse['cardName']
                    merchant_data['account_bank'] = reaponse['bankName']
                    merchant_data['account_number'] = reaponse['card']
                    if 'latitude' in reaponse:
                        merchant_data['latitude'] = reaponse['latitude']
                    if 'longitude' in reaponse:
                        merchant_data['longitude'] = reaponse['longitude']
                    card_copy = f'youhuiquanyi/{business_no}/card_copy.png'
                    card_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/cardFace.png', key=card_copy)
                    if card_copy_url:
                        merchant_data['card_copy'] = card_copy
                    merchant_data['identification_number'] = reaponse['identity']
                    merchant_data['store_address'] = reaponse['address']
                    store_header_copy = f'youhuiquanyi/{business_no}/store_header_copy.png'
                    store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                    if store_header_copy_url:
                        merchant_data['store_header_copy'] = store_header_copy
                    merchant, cereate = Merchant.objects.update_or_create(defaults=merchant_data, wyfMerchantID=business_no)
                    if not merchant.managerName:
                        merchant.managerName = reaponse['keeper']
                    if not merchant.managermobile:
                        merchant.managermobile = reaponse['phone']
                    if not merchant.prov_name:
                        merchant.prov_name = reaponse['province']
                        merchant.city_name = reaponse['city']
                        merchant.district_name = reaponse['area']
                    if not merchant.business_category:
                        merchant.business_category_id = 1
                    if not merchant.store_logo_copy:
                        merchant.store_logo_copy = 'default_merchant_logo.jpg'
                    merchant.save()
                    if cereate and merchant.channel:
                        store_header_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                        if store_header_copy_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=store_header_copy)
                        store_indoor_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        store_indoor_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/otherPhoto3.png', key=store_indoor_copy)
                        if store_indoor_copy_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=store_indoor_copy)
                        merchantCheck = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        merchantCheck_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantCheck.png', key=merchantCheck)
                        if merchantCheck_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=merchantCheck)
                    merchantchannel_data = {
                        'merchant_id': merchant.id
                    }
                    if reaponse['allchannelJson']['channel_ruiyinxin']:
                        if reaponse['allchannelJson']['channel_ruiyinxin']['status'] == 1:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                            merchantchannel_data['channel_id'] = 2
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                    if reaponse['allchannelJson']['channel_sxf_tq']:
                        if reaponse['allchannelJson']['channel_sxf_tq']['status'] == 1:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_4'] if 'merchant_other_4' in reaponse['allchannelJson']['channel_sxf_tq'] else ''
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_no']
                            merchantchannel_data['channel_id'] = 3
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                    if reaponse['channel_mch_id'] == '227823797':
                        try:
                            channel_url = 'https://manage.gdwxyf.com/internal/searchmerchantchannelmsg.do'
                            channel_body = {"account": "gdyouzheng", "shopId": sign}
                            channel_response = requests.post(url=channel_url, data=channel_body)
                            channel_result = channel_response.json()
                            merchantchannel_data['smid'] = channel_result['alipaychannelJson']['merchant_other_4'] if 'merchant_other_4' in channel_result['alipaychannelJson'] else ''
                            merchantchannel_data['channel_mchid'] = channel_result['alipaychannelJson']['upMerchantNo']
                            merchantchannel_data['channel_id'] = 15
                            merchantchannel_data['sub_mchid'] = channel_result['wxchannelJson']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                        except:
                            pass
                    transaction.savepoint_commit(save_id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '获取商户信息错误,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        data = MerchantInfoRetrieveModelSerializer(merchant).data
        merchantenter = MerchantEnter.objects.filter(merchant_id=merchant.id, level_id=user.level_id).first()
        if merchantenter:
            if merchantenter.managerName:
                data['managerName'] = merchantenter.managerName
                data['managermobile'] = merchantenter.managermobile
        return Response(data, status=status.HTTP_200_OK)

    def sms_codes(self, request):
        managermobile = self.request.query_params.get('managermobile', None)
        if not managermobile:
            return Response({'error': '缺少手机号码'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', managermobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn = get_redis_connection("verify_code")
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % managermobile, 300, sms_code)
        pl.setex('send_flag_%s' % managermobile, 60, 1)
        pl.execute()
        content = f'【微邮付】登录验证码为：{sms_code}，若非本人操作，请忽略。'
        result = common_msg(managermobile, content)
        return Response({"success": "发送短信验证码成功"}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        managerName = self.request.data.get('managerName', None)
        managermobile = self.request.data.get('managermobile', None)
        sms_code = self.request.data.get('sms_code', None)
        user = self.request.iser
        merchantenter = MerchantEnter.objects.filter(level_id=user.level_id, merchant_id=instance.id).first()
        if not merchantenter:
            return Response({'error': '无效商户,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        if managermobile:
            if not sms_code:
                return Response({"error": "请输入手机验证码"}, status=status.HTTP_400_BAD_REQUEST)
            if not re.match(r'^1[3-9]\d{9}$', managermobile):
                return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
            redis_conn = get_redis_connection("verify_code")
            sms_code_server = redis_conn.get("sms_%s" % managermobile)
            if sms_code_server is None:
                return Response({'error': "短信验证码失效"}, status=status.HTTP_400_BAD_REQUEST)
            sms_code_server = sms_code_server.decode()
            if sms_code_server != str(sms_code):
                return Response({'error': "输入验证码有误"}, status=status.HTTP_400_BAD_REQUEST)
            redis_conn.delete("sms_%s" % managermobile)
            merchantenter.managermobile = managermobile
        if managerName:
            merchantenter.managerName = managerName
        merchantenter.save()
        return Response({'success': '修改成功'}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        instance = self.get_object()
        managerName = self.request.data.get('managerName', None)
        managermobile = self.request.data.get('managermobile', None)
        if not all([managerName, managermobile]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', managermobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        user = self.request.iser
        merchantenter_data = {}
        merchantenter_data['merchant_id'] = instance.id
        merchantenter_data['level_id'] = user.level_id
        merchantenter_data['user_id'] = user.id
        merchantenter_data['create_time'] = datetime.datetime.now()
        merchantenter_data['managerName'] = managerName
        merchantenter_data['managermobile'] = managermobile
        merchantenter, create = MerchantEnter.objects.update_or_create(defaults=merchantenter_data, merchant_id=merchantenter_data['merchant_id'], level_id=merchantenter_data['level_id'])
        if create:
            instance.branch_num += 1
            instance.save()
            goods_set = instance.goods_set.all()
            for goods in goods_set:
                launchedgoods_data = {}
                launchedgoods_data['level_id'] = merchantenter.level_id
                launchedgoods_data['goods_id'] = goods.id
                launchedgoods_data['is_launched'] = 0
                launchedgoods_data['name'] = goods.name
                launchedgoods_data['category_id'] = 1
                launchedgoods_data['stock'] = 0
                LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=merchantenter.level_id, goods_id=goods.id)
        return Response({'success': '添加成功', 'merchant_id': instance.id}, status=status.HTTP_200_OK)

    def up_merchant(self, request):
        user = self.request.iser
        level = user.level
        merchant_id = self.request.data.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少商户参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall != 2:
            return Response({'error': '商户商圈状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        instance = MerchantEnter.objects.filter(level_id=level.id, merchant_id=merchant_id).update(is_online=2)
        return Response({'success': '上架成功'}, status=status.HTTP_200_OK)

    def down_merchant(self, request):
        user = self.request.iser
        level = user.level
        merchant_id = self.request.data.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少商户参数'}, status=status.HTTP_400_BAD_REQUEST)
        instance = MerchantEnter.objects.filter(level_id=level.id, merchant_id=merchant_id).update(is_online=3)
        return Response({'success': '下架架成功'}, status=status.HTTP_200_OK)

    def check_pay_qrcode(self, request):
        user = self.request.iser
        pay_sn = self.request.data.get('pay_sn', None)
        if not pay_sn:
            return Response({'error': '请上传收款码sn码'}, status=status.HTTP_400_BAD_REQUEST)
        pay_sn = pay_sn.replace('http://pay.gdwxyf.com/pay/scancode.do?', '')
        url = 'https://manage.gdwxyf.com/internal/searchqrcode.do'
        body = {
            "simpleCode": pay_sn,
            "shopId": "",
            "account": "gdyouzheng",
            "branchId": "2",
        }
        try:
            response = requests.post(url=url, data=body)
            result = response.json()['list']
        except:
            return Response({'error1': '系统繁忙', 'error2': '请重新扫码'}, status=status.HTTP_400_BAD_REQUEST)
        if not result:
            return Response({'error1': '收款码识别失败,请核实是否微邮付收款码', 'error2': "请确认码牌是否正确或者是否为广东微邮付商户"}, status=status.HTTP_400_BAD_REQUEST)
        result = result[0]
        data = {}
        data['business_no'] = result['shop_account']
        data['merchant_name'] = result['shopName']
        data['short_name'] = result['shopNicknName']
        data['pay_sn'] = pay_sn
        merchant = Merchant.objects.filter(wyfMerchantID=result['shop_account']).first()
        if not merchant:
            sign = result['shopId']
            business_no = result['shop_account']
            url = 'https://manage.gdwxyf.com/internal/searchmerchantbyshopids.do'
            body = {
                'account': 'gdyouzheng',
                'shopId': result['shopId']
            }
            reaponse = requests.post(url=url, data=body)
            try:
                reaponse = reaponse.json()
            except:
                return Response({'error1': '系统繁忙', 'error2': '请重新扫码'}, status=status.HTTP_400_BAD_REQUEST)
            if 'wx_channel_merchant_id' not in reaponse:
                return Response({'error': '商户号有误,请检查重新操作', 'error1': '商户号有误', 'error2': '请检查重新操作'}, status=status.HTTP_400_BAD_REQUEST)
            if reaponse['wx_channel_merchant_id'] == '':
                return Response({'error': '获取商户信息失败，请确认该商户是否审核成功。', 'error1': '获取商户信息失败', 'error2': '请确认该商户是否审核成功'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    merchant_data = {}
                    channel_mch_id = reaponse['channel_mch_id']
                    channel = Channel.objects.filter(mchid=channel_mch_id).first()
                    if channel:
                        merchant_data['channel_id'] = channel.id
                    merchant_data['name'] = reaponse['shopName']
                    merchant_data['short_name'] = reaponse['shopNickname']
                    merchant_data['wyfMerchantID'] = business_no
                    merchant_data['ruiyinxinMerchantID'] = sign
                    merchant_data['create_time'] = datetime.datetime.now()
                    if reaponse['businessType'] == '1':
                        merchant_data['subject_type'] = 3
                    elif reaponse['businessType'] == '2':
                        merchant_data['subject_type'] = 2
                    elif reaponse['businessType'] == '3':
                        merchant_data['subject_type'] = 1
                    else:
                        merchant_data['subject_type'] = 4
                    level = Level.objects.filter(acceptId=reaponse['accept_id']).first()
                    if level:
                        merchant_data['level_id'] = level.id
                    merchantuser, create = MerchantUser.objects.get_or_create(mobile=reaponse['phone'], defaults={"mobile": reaponse['phone']})
                    merchant_data['merchantuser_id'] = merchantuser.id
                    merchant_data['account_name'] = reaponse['cardName']
                    merchant_data['account_bank'] = reaponse['bankName']
                    merchant_data['account_number'] = reaponse['card']
                    card_copy = f'youhuiquanyi/{business_no}/card_copy.png'
                    card_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/cardFace.png', key=card_copy)
                    if card_copy_url:
                        merchant_data['card_copy'] = card_copy
                    merchant_data['identification_number'] = reaponse['identity']
                    merchant_data['store_address'] = reaponse['address']
                    store_header_copy = f'youhuiquanyi/{business_no}/store_header_copy.png'
                    store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                    if store_header_copy_url:
                        merchant_data['store_header_copy'] = store_header_copy
                    merchant, cereate = Merchant.objects.update_or_create(defaults=merchant_data, wyfMerchantID=business_no)
                    if not merchant.managerName:
                        merchant.managerName = reaponse['keeper']
                    if not merchant.managermobile:
                        merchant.managermobile = reaponse['phone']
                    if not merchant.prov_name:
                        merchant.prov_name = reaponse['province']
                        merchant.city_name = reaponse['city']
                        merchant.district_name = reaponse['area']
                    if not merchant.business_category:
                        merchant.business_category_id = 1
                    if not merchant.store_logo_copy:
                        merchant.store_logo_copy = 'default_merchant_logo.jpg'
                    merchant.save()
                    if cereate and merchant.channel:
                        store_header_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                        if store_header_copy_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=store_header_copy)
                        store_indoor_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        store_indoor_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/otherPhoto3.png', key=store_indoor_copy)
                        if store_indoor_copy_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=store_indoor_copy)
                        merchantCheck = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        merchantCheck_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantCheck.png', key=merchantCheck)
                        if merchantCheck_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=merchantCheck)
                    merchantchannel_data = {
                        'merchant_id': merchant.id
                    }
                    if reaponse['allchannelJson']['channel_ruiyinxin']:
                        if reaponse['allchannelJson']['channel_ruiyinxin']['status'] == 1:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                            merchantchannel_data['channel_id'] = 2
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                    if reaponse['allchannelJson']['channel_sxf_tq']:
                        if reaponse['allchannelJson']['channel_sxf_tq']['status'] == 1:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_4'] if 'merchant_other_4' in reaponse['allchannelJson']['channel_sxf_tq'] else ''
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_no']
                            merchantchannel_data['channel_id'] = 3
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                    transaction.savepoint_commit(save_id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '获取商户信息错误,请联系管理员', 'error1': '获取商户信息错误', 'error2': '请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        check_business_qrcode = MerchantBusinessQRCode.objects.filter(merchant_id=merchant.id).first()
        if check_business_qrcode:
            return Response({'error': f'该商户({result["shopName"]})无权限操作,(当前用户所属机构{user.level.name})', 'error1': f'该商户({result["shopName"]})已绑定商圈码({check_business_qrcode.sn})', 'error2': f'(请勿重复绑定)'}, status=status.HTTP_400_BAD_REQUEST)
        level = merchant.level
        if level:
            data['level_name'] = level.name
            data['merchant_id'] = merchant.id
            level_list = get_level_list(user.level)
            if level.id in level_list:
                return Response(data, status=status.HTTP_200_OK)
            else:
                return Response({'error': f'该商户({result["shopName"]})无权限操作,(当前用户所属机构{user.level.name})', 'error1': f'该商户({result["shopName"]})无权限操作', 'error2': f'(当前用户所属机构{user.level.name})'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': f'该商户({result["shopName"]})无权限操作', 'error1':  f'该商户({result["shopName"]})无权限操作', 'error2': '请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def check_business_qrcode(self, request):
        business_qrcode = self.request.data.get('business_qrcode', None)
        if not business_qrcode:
            return Response({'error': '请上传商圈码信息'}, status=status.HTTP_400_BAD_REQUEST)
        business_qrcode = business_qrcode.replace('https://qrcode.sutpay.com/business/business_district/?shop_id=', '')
        try:
            instance = MerchantBusinessQRCode.objects.get(sn=business_qrcode)
        except:
            return Response({'error': '无效商圈码信息'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.merchant_id:
            return Response({'error': '该商圈码已被绑定, 请重新换一张新的商圈码牌进行扫码'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'business_qrcode': business_qrcode}, status=status.HTTP_200_OK)

    def bind_business_qrcode(self, request):
        user = self.request.iser
        merchant_id = self.request.data.get('merchant_id', None)
        business_qrcode = self.request.data.get('business_qrcode', None)
        if not merchant_id:
            return Response({'error': '请上传商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if not business_qrcode:
            return Response({'error': '请上传商圈码信息'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        check_business_qrcode = MerchantBusinessQRCode.objects.filter(merchant_id=merchant.id)
        if check_business_qrcode:
            return Response({'error': f'该商户已绑过商圈码,不可重复绑定'}, status=status.HTTP_400_BAD_REQUEST)
        business_qrcode = business_qrcode.replace('https://qrcode.sutpay.com/business/business_district/?shop_id=', '')
        try:
            instance = MerchantBusinessQRCode.objects.get(sn=business_qrcode)
        except:
            return Response({'error': '无效商圈码信息'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.is_bind == 1:
            return Response({'error': '该商圈码已被绑定, 请重新换一张新的商圈码牌进行扫码'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.merchant_id:
            return Response({'error': '该商圈码已被绑定, 请重新换一张新的商圈码牌进行扫码'}, status=status.HTTP_400_BAD_REQUEST)
        instance.merchant_id = merchant_id
        instance.bind_time = datetime.datetime.now()
        instance.user_id = user.id
        instance.is_bind = 1
        instance.level_id = merchant.level_id
        instance.save()
        companyuser = instance.user
        companyuser_id = companyuser.id
        date_now = datetime.datetime.now()
        nonce_str = random_str()
        cash_activity_id = 355
        amount = Decimal('5')
        cash_activity = CashActivity.objects.get(id=cash_activity_id)
        cashactivitydata_data = {}
        cashactivitydata_data['companyuser_id'] = companyuser_id
        cashactivitydata_data['cash_activity_id'] = cash_activity.id
        cashactivitydata_data['amount'] = amount
        cashactivitydata_data['create_time'] = date_now
        cashactivitydata_data['nonce_str'] = nonce_str
        cashactivitydata_data['desc'] = cash_activity.name
        cashactivitydata_data['mobile'] = companyuser.mobile
        cashactivitydata_data['openid'] = companyuser.openid
        cashactivitydata_data['appid'] = 'wxb67b94c00d7cd83f'
        cashactivitydata_data['partner_trade_no'] = f'{date_now.strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}{"%06d" % companyuser_id}'
        cashactivitydata = CashActivityData.objects.create(**cashactivitydata_data)
        while True:
            activity = CashActivity.objects.get(id=cash_activity_id)
            activity_origin_take_amount = activity.take_amount
            activity_origin_remain_amount = activity.remain_amount
            activity_new_take_amount = activity_origin_take_amount + amount
            activity_new_remain_amount = activity_origin_remain_amount - amount
            result = CashActivity.objects.filter(take_amount=activity_origin_take_amount,
                                                 remain_amount=activity_origin_remain_amount,
                                                 id=cash_activity_id).update(
                take_amount=activity_new_take_amount, remain_amount=activity_new_remain_amount)
            if result == 0:
                continue
            break
        instance.cashactivitydata_id = cashactivitydata.id
        # instance.is_achieve = 1
        # instance.award_time = date_now
        instance.save()
        return Response({'success': '操作成功', 'bind_time': instance.bind_time.strftime('%Y-%m-%d %H:%M:%S')}, status=status.HTTP_200_OK)

    def open_is_mall(self, request):
        user = self.request.iser
        merchant_id = self.request.data.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = self.get_queryset().filter(id=merchant_id).first()
        if not merchant:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall != 0:
            return Response({'error': '商户商圈状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        '''校验商户当前通道'''
        try:
            url = 'https://api.gdwxyf.com/api/searchmerchantmsg.do'
            key = '6715C7D4435343BA0459EAEC2334D81B'
            body = {
                "program_id": "202316837141378884",
                "shop_id": merchant.wyfMerchantID
            }
            sign = get_sign(body, key)
            body['sign'] = sign
            response = requests.post(url=url, json=body)
            result = response.json()
            if result['pay_type'] != 'sxf_tq':
                return Response({'error': '商户通道不支持入驻商圈'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            pass
        # check_merhant_channel = MerchantChannel.objects.filter(merchant_id=merchant_id, channel_id=3)
        # if not check_merhant_channel:
        if merchant.channel_id != 3:
            return Response({'error': '商户通道不支持入驻商圈'}, status=status.HTTP_400_BAD_REQUEST)
        '''商户授权应用id'''
        url = 'https://api.gdwxyf.com/api/shopBindApp.do'
        key = '6715C7D4435343BA0459EAEC2334D81B'
        body = {
            "program_id": "202316837141378884",
            "shop_id": merchant.wyfMerchantID
        }
        sign = get_sign(body, key)
        body['sign'] = sign
        response = requests.post(url=url, json=body)
        result = response.json()
        if result['result_code'] != 'success' and result['error_msg'] != '商户与应用已绑定，请勿重复绑定。':
            return Response({'error': result['error_msg']}, status=status.HTTP_400_BAD_REQUEST)
        '''商户绑定授权appid'''
        url = 'https://api.gdwxyf.com/api/setMerchantWxAppMsg.do'
        body = {
            "program_id": "202316837141378884",
            "shop_id": merchant.ruiyinxinMerchantID,
            "config_type": 'appid',
            "appid": "wx950122ad80dc97c9"
        }
        sign = get_sign(body, key)
        body['sign'] = sign
        response = requests.post(url=url, json=body)
        result = response.json()
        if result['result_code'] != 'success' and result['error_msg'] != '微信公众号配置已配置':
            if result['error_msg'] != 'INVALID_REQUEST:subappid已配置，请勿重复配置':
                return Response({'error': result['error_msg']}, status=status.HTTP_400_BAD_REQUEST)
        merchant.is_mall = 1
        merchant.save()
        mall_apply_data = {}
        mall_apply_data['merchant_id'] = merchant.id
        mall_apply_data['applyment_state'] = 0
        mall_apply_data['applyment_type'] = 1
        mall_apply_data['verify_user_id'] = user.id
        instance, create = MerchantMallApplyment.objects.get_or_create(defaults=mall_apply_data, merchant_id=merchant.id, applyment_state=0, applyment_type=1)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def confirm_is_mall(self, request):
        user = self.request.iser
        merchant_id = self.request.data.get('merchant_id', None)
        reject_reason = self.request.data.get('reject_reason', None)
        applyment_state = self.request.data.get('applyment_state', None)
        datetime_now = datetime.datetime.now()
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = self.get_queryset().filter(id=merchant_id).first()
        if not merchant:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall != 5:
            return Response({'error': '商户商圈状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        mall_applyment = MerchantMallApplyment.objects.filter(merchant_id=merchant.id, applyment_type=1).last()
        if str(applyment_state) == '1':
            try:
                '''创建门店'''
                url = 'https://manage.gdwxyf.com/internal/savebranchstoremsg.do'
                body = {
                    "deviceName": "微邮惠商圈",
                    "shopId": merchant.wyfMerchantID,
                    "account": "gdyouzheng"
                }
                response = requests.post(url=url, data=body)
                result = response.json()
                device_id = result['device_id']
                '''绑定设备id'''
                url = 'https://manage.gdwxyf.com/internal/savenewqrcode.do'
                body = {
                    "deviceName": "微邮惠商圈",
                    "shopId": merchant.wyfMerchantID,
                    "wsyDeviceId": f'{merchant.wyfMerchantID}2024',
                    "deviceId": device_id
                }
                response = requests.post(url=url, data=body)
                result = response.json()
                if result['result_code'] == 'fail':
                    return Response({'error': result['error_msg']}, status=status.HTTP_400_BAD_REQUEST)
            except:
                return Response({'error': '创建门店失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            merchant.is_mall = 2
            merchant.device = f'{merchant.wyfMerchantID}2024'
            merchant.applyment_state = 2
            merchant.verify_state = 2
            merchant.is_profit_share = 4
            merchant.save()
            if mall_applyment:
                mall_applyment.applyment_state = 2
                mall_applyment.audit_time = datetime_now
                mall_applyment.verify_state = 2
                mall_applyment.verify_time = datetime_now
                mall_applyment.verify_user_id = user.id
                mall_applyment.save()
            return Response({'success': '审核成功'}, status=status.HTTP_200_OK)
        elif str(applyment_state) == '2':
            merchant.is_mall = 5
            merchant.applyment_state = 3
            merchant.save()
            if mall_applyment:
                mall_applyment.applyment_state = 3
                mall_applyment.audit_time = datetime_now
                mall_applyment.reject_reason = reject_reason
                mall_applyment.verify_user_id = user.id
                mall_applyment.save()
            return Response({'success': '驳回成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '审核参数有误'}, status=status.HTTP_400_BAD_REQUEST)


class GoodsModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'merchant__name', 'merchant__wyfMerchantID')
    filter_class = GoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return GoodsListModelSerializer
        else:
            return GoodsRetrieveModelSerializer

    def get_queryset(self):
        user = self.request.iser
        level_id = user.level_id
        sale_sort = self.request.query_params.get('sale_sort', None)
        price_sort = self.request.query_params.get('price_sort', None)
        soldout = self.request.query_params.get('soldout', '')
        good_is_launched = self.request.query_params.get('good_is_launched', None)
        goods_tag = self.request.query_params.get('goods_tag', None)
        # queryset = Goods.objects.filter(launchedgoods__level_id=level_id).distinct().order_by('-launchedgoods__stock')
        queryset = Goods.objects.filter(merchant__merchantenter__level_id=level_id).distinct() #.order_by('-launchedgoods__stock')
        if soldout == '1':
            queryset = queryset.filter(launchedgoods__stock__gt=0)
        elif soldout == '2':
            queryset = queryset.filter(launchedgoods__stock=0)
        if good_is_launched == '0':
            queryset = queryset.filter(launchedgoods__is_launched="0", is_launched=1, launchedgoods__level_id=level_id)
        if good_is_launched == '1':
            queryset = queryset.filter(launchedgoods__is_launched="1", is_launched=1, launchedgoods__level_id=level_id)
        if sale_sort == '1':
            queryset = queryset.order_by('sales', 'id')
        elif sale_sort == '2':
            queryset = queryset.order_by('-sales', 'id')
        if price_sort == '1':
            queryset = queryset.order_by('price', 'id')
        elif price_sort == '2':
            queryset = queryset.order_by('-price', 'id')
        if goods_tag:
            queryset = queryset.filter(goods_tag=goods_tag)
        queryset = queryset.order_by('-id')
        return queryset.filter(equityID__isnull=True).distinct()

    def get_serializer_context(self):
        user = self.request.iser
        return {'user': user}

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        user = self.request.iser
        queryset1 = queryset.filter(is_launched=1)
        on__count = queryset1.filter(launchedgoods__is_launched=1, launchedgoods__level_id=user.level_id).count()
        down__count = queryset1.count() - on__count
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['on__count'] = str(on__count)
        self.request.data['down__count'] = str(down__count)
        # is_launched = self.request.query_params.get('is_launched', None)
        # if is_launched in ['0', '1']:
        #     if is_launched == '0':
        #         queryset = queryset.exclude(launchedgoods__is_launched=1, launchedgoods__level_id=user.level_id)
        #     else:
        #         queryset = queryset.filter(launchedgoods__is_launched=1, launchedgoods__level_id=user.level_id)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def upload_image(self, request):
        user = self.request.iser
        img = self.request.FILES.get('img', None)
        business_no = self.request.data.get('business_no', None)
        if not all([img]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        # try:
        #     merchant = Merchant.objects.get(wyfMerchantID=business_no)
        # except:
        #     return Response({'error': '无效商户号'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            img_id = f'youhuiquanyi/goods_image{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'success': '操作成功', 'img_id': f'https://circle.sutpay.cn/{img_id}'}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        user = self.request.iser
        modify_type = self.request.data.get('modify_type', '1')
        is_launched = self.request.data.get('is_launched', None)
        name = self.request.data.get('name', None)
        stock = self.request.data.get('stock', None)
        if str(modify_type) == '2':
            launched_goods = LaunchedGoods.objects.filter(goods_id=instance.id, level_id=user.level_id).first()
            if not launched_goods:
                launchedgoods_data = {}
                launchedgoods_data['level_id'] = user.level_id
                launchedgoods_data['goods_id'] = instance.id
                launchedgoods_data['is_launched'] = is_launched
                launchedgoods_data['name'] = name
                launchedgoods_data['category_id'] = 1
                launchedgoods_data['stock'] = stock
                launched_goods, create = LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=user.level_id, goods_id=instance.id)
            else:
                launched_goods.is_launched = is_launched
                launched_goods.stock = stock
                launched_goods.save()
            instance.remain_stock = instance.remain_stock + Decimal(stock) - launched_goods.stock
            instance.save()
            return Response({'success': '修改成功'}, status=status.HTTP_200_OK)
        if instance.is_launched == 2:
            return Response({'error': '已存在待审核修改单,请耐心等待客服审核'}, status=status.HTTP_400_BAD_REQUEST)
        applyment = GoodsModifyApplyment.objects.filter(goods_id=instance.id, companyuser_id=user.id, applyment_status=1)
        if applyment:
            return Response({'error': '已存在待审核修改单,请耐心等待客服审核'}, status=status.HTTP_400_BAD_REQUEST)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        desc_pack = self.request.data.get('desc_pack', '')
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        goods_tag_id = self.request.data.get('goods_tag_id', None)
        proof = self.request.data.get('proof', None)
        if not name:
            return Response({'error': '请输入商品名称。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(name) > 128:
            return Response({'error': '您输入的商品名称有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not caption:
            return Response({'error': '请输入商品品牌。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(caption) > 50:
            return Response({'error': '您输入的品牌有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not desc_detail:
            return Response({'error': '请输入商品介绍。'}, status=status.HTTP_400_BAD_REQUEST)
        if not default_image:
            return Response({'error': '请输入商品封面图。'}, status=status.HTTP_400_BAD_REQUEST)
        if not manufacturer:
            return Response({'error': '请输入商品厂商。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(manufacturer) > 32:
            return Response({'error': '您输入的厂商有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not specifications:
            return Response({'error': '请输入商品规格。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(specifications) > 32:
            return Response({'error': '您输入的商品规格有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not image_array:
            return Response({'error': '请输入商品轮播图。'}, status=status.HTTP_400_BAD_REQUEST)
        if not proof:
            return Response({'error': '请输入商品凭证。'}, status=status.HTTP_400_BAD_REQUEST)
        if goods_tag_id:
            goods_tag_activity_level = GoodsTagActivityLevelRelation.objects.filter(id=goods_tag_id).first()
            if not goods_tag_activity_level:
                return Response({'error': '无效标签活动id'}, status=status.HTTP_400_BAD_REQUEST)
            goods_tag = goods_tag_activity_level.goods_tag_activity.goods_tag
        else:
            goods_tag = ''
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        applyment_status = 0
        old_goods = GoodsRetrieveModelSerializer(instance).data
        launched_goods = LaunchedGoods.objects.filter(goods_id=instance.id, level_id=user.level_id).first()
        if not launched_goods:
            launchedgoods_data = {}
            launchedgoods_data['level_id'] = user.level_id
            launchedgoods_data['goods_id'] = instance.id
            launchedgoods_data['is_launched'] = is_launched
            launchedgoods_data['name'] = name
            launchedgoods_data['category_id'] = 1
            launchedgoods_data['stock'] = stock
            launched_goods, create = LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=user.level_id, goods_id=instance.id)
        check_word = ['name', 'desc_detail', 'price', 'default_image', 'manufacturer', 'specifications', 'market_price', 'caption', 'desc_pack', 'proof']
        update_word = []
        try:
            if old_goods['goodsimage_set'] != self.request.data.get('image_array', None):
                applyment_status = 1
                update_word.append('goodsimage_set')
        except:
            pass
        for word in check_word:
            try:
                if word in ['price', 'market_price']:
                    if Decimal(old_goods[word]) != Decimal(self.request.data.get(word, None)):
                        applyment_status = 1
                        update_word.append(word)
                else:
                    if old_goods[word] != self.request.data.get(word, None):
                        applyment_status = 1
                        update_word.append(word)
            except:
                pass
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                if applyment_status:
                    if user.role_id == 3:
                        is_launched1 = 4
                    else:
                        is_launched1 = 2
                    instance.name = name
                    instance.caption = caption
                    instance.desc_detail = desc_detail
                    instance.desc_pack = desc_pack
                    instance.price = price
                    instance.market_price = market_price
                    instance.default_image = default_image.replace('https://circle.sutpay.cn/', '')
                    instance.manufacturer = manufacturer
                    instance.specifications = specifications
                    instance.is_launched = is_launched1
                    instance.goods_tag = goods_tag
                    instance.proof = proof.replace('https://circle.sutpay.cn/', '')
                    instance.remain_stock = instance.remain_stock + Decimal(stock) -launched_goods.stock
                    instance.save()
                    applyment_data = {}
                    for word in update_word:
                        if word != 'goodsimage_set':
                            applyment_data[word] = old_goods[word]
                    if old_goods['goodsimage_set'] != self.request.data.get('image_array', None):
                        goodsimage_set = instance.goodsimage_set.all().delete()
                        applyment_data['image_array'] = json.dumps(old_goods['goodsimage_set'])
                        for image in image_array:
                            GoodsImage.objects.create(
                                goods_id=instance.id,
                                image=image.replace('https://circle.sutpay.cn/', '')
                            )
                    applyment_data['create_time'] = datetime.datetime.now()
                    applyment_data['is_launched'] = launched_goods.is_launched
                    applyment_data['stock'] = launched_goods.stock
                    applyment_data['goods_id'] = instance.id
                    applyment_data['companyuser_id'] = user.id
                    applyment_data['level_id'] = user.level_id
                    applyment_data['update_word'] = json.dumps(update_word)
                    applyment, create = GoodsModifyApplyment.objects.get_or_create(goods_id=instance.id, companyuser_id=user.id, applyment_status=1, defaults=applyment_data)
                    launched_goods.is_launched = is_launched
                    launched_goods.stock = stock
                    launched_goods.save()
                    # applyment_data = {}
                    # applyment_data['name'] = old_goods['name']
                    # applyment_data['caption'] = old_goods['caption']
                    # applyment_data['desc_detail'] = old_goods['desc_detail']
                    # applyment_data['price'] = old_goods['price']
                    # applyment_data['market_price'] = old_goods['market_price']
                    # applyment_data['default_image'] = old_goods['default_image'].replace('https://circle.sutpay.cn', '')
                    # applyment_data['stock'] = launched_goods.stock
                    # applyment_data['goods_id'] = instance.id
                    # applyment_data['merchant_id'] = instance.merchant_id
                    # applyment_data['companyuser_id'] = user.id
                    # applyment_data['manufacturer'] = old_goods['manufacturer']
                    # applyment_data['specifications'] = old_goods['specifications']
                    # applyment_data['is_launched'] = is_launched
                    # applyment_data['create_time'] = datetime.datetime.now()
                    # applyment, create = GoodsModifyApplyment.objects.get_or_create(goods_id=instance.id, companyuser_id=user.id, applyment_status=1, defaults=applyment_data)
                    # goodsimage_set = instance.goodsimage_set.all().update(is_default=0, applyment_id=applyment.id)
                    # for image in image_array:
                    #     GoodsImage.objects.create(
                    #         goods_id=instance.id,
                    #         image=image.replace('https://circle.sutpay.cn/', '')
                    #     )
                else:
                    instance.remain_stock = instance.remain_stock + Decimal(stock) -launched_goods.stock
                    instance.save()
                    applyment_data = {}
                    # applyment_data['name'] = old_goods['name']
                    # applyment_data['caption'] = old_goods['caption']
                    # applyment_data['desc_detail'] = old_goods['desc_detail']
                    # applyment_data['price'] = old_goods['price']
                    # applyment_data['market_price'] = old_goods['market_price']
                    # applyment_data['default_image'] = old_goods['default_image'].replace('https://circle.sutpay.cn', '')
                    applyment_data['stock'] = launched_goods.stock
                    # applyment_data['goods_id'] = instance.id
                    # applyment_data['merchant_id'] = instance.merchant_id
                    # applyment_data['companyuser_id'] = user.id
                    # applyment_data['manufacturer'] = old_goods['manufacturer']
                    # applyment_data['specifications'] = old_goods['specifications']
                    applyment_data['is_launched'] = launched_goods.is_launched
                    applyment_data['applyment_status'] = 2
                    applyment_data['create_time'] = datetime.datetime.now()
                    applyment, create = GoodsModifyApplyment.objects.get_or_create(goods_id=instance.id, companyuser_id=user.id, applyment_status=1, defaults=applyment_data)
                    launched_goods.stock = stock
                    launched_goods.is_launched = is_launched
                    launched_goods.save()
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '提交修改成功'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                # error_enum = {
                #     "name": '商品名称',
                #     "caption": '品牌',
                #     "desc_detail": '商品介绍',
                #     "market_price": '市场价',
                #     "default_image": '商品封面图',
                #     "manufacturer": '厂商',
                #     "specifications": '规格',
                #     "remain_stock": '库存',
                #     "image": '商品轮播图',
                #     'decimal': '库存'
                # }
                # for key, value in error_enum.items():
                #     if key in e.__str__():
                #         result = f'您输入的{value}有误，请重新输入。'
                #         break
                #     else:
                #         result = f'提交失败,请联系管理员处理。'
                return Response({'error': '提交失败,请联系管理员处理。'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
        return Response({'success': '提交修改成功,请耐心等待客服审核生效'}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        desc_pack = self.request.data.get('desc_pack', '')
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        stock = self.request.data.get('stock', None)
        merchant_id = self.request.data.get('merchant_id', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        is_launched = self.request.data.get('is_launched', None)
        barcode = self.request.data.get('barcode', None)
        goods_tag_id = self.request.data.get('goods_tag_id', None)
        proof = self.request.data.get('proof', None)
        if not all([name, caption, desc_detail, price, market_price, default_image, image_array, stock, merchant_id, manufacturer, specifications]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        # check_goods = Goods.objects.filter(merchant_id=merchant_id, name=name)
        # if check_goods:
        #     return Response({'error': '重复商品名称'}, status=status.HTTP_400_BAD_REQUEST)
        if user.role_id == 3:
            is_launched1 = 4
        else:
            is_launched1 = 2
        if goods_tag_id:
            goods_tag_activity_level = GoodsTagActivityLevelRelation.objects.filter(id=goods_tag_id, level_id=user.level_id).first()
            if not goods_tag_activity_level:
                return Response({'error': '无效标签活动id'}, status=status.HTTP_400_BAD_REQUEST)
            goods_tag = goods_tag_activity_level.goods_tag_activity.goods_tag
        else:
            goods_tag = ''
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                goods_data = {}
                goods_data['name'] = name
                goods_data['caption'] = caption
                goods_data['category_id'] = 1
                goods_data['desc_detail'] = desc_detail
                goods_data['desc_pack'] = desc_pack
                goods_data['price'] = price
                goods_data['market_price'] = market_price
                goods_data['default_image'] = default_image.replace('https://circle.sutpay.cn/', '')
                goods_data['stock'] = 0
                goods_data['merchant_id'] = merchant_id
                goods_data['manufacturer'] = manufacturer
                goods_data['specifications'] = specifications
                goods_data['is_launched'] = is_launched1
                goods_data['remain_stock'] = stock
                goods_data['is_settlement'] = 1
                goods_data['longitude'] = merchant.longitude
                goods_data['latitude'] = merchant.latitude
                goods_data['order_species'] = 2
                goods_data['goods_tag'] = goods_tag
                if proof:
                    goods_data['proof'] = proof.replace('https://circle.sutpay.cn/', '')
                area = GoodsAreaCode.objects.filter(district_name=merchant.district_name, prov_name=merchant.prov_name, city_name=merchant.city_name).first()
                if area:
                    goods_data['area_id'] = area.id
                instance = Goods.objects.create(**goods_data)
                for image in image_array:
                    GoodsImage.objects.create(
                        goods_id=instance.id,
                        image=image.replace('https://circle.sutpay.cn/', '')
                    )
                launchedgoods_data = {}
                launchedgoods_data['level_id'] = user.level_id
                launchedgoods_data['goods_id'] = instance.id
                launchedgoods_data['is_launched'] = is_launched
                launchedgoods_data['name'] = name
                launchedgoods_data['category_id'] = 1
                launchedgoods_data['stock'] = stock
                LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=user.level_id, goods_id=instance.id)
                applyment_data = {}
                # applyment_data['name'] = name
                # applyment_data['caption'] = caption
                # applyment_data['desc_detail'] = desc_detail
                # applyment_data['price'] = price
                # applyment_data['market_price'] = market_price
                # applyment_data['default_image'] = default_image
                # applyment_data['stock'] = stock
                applyment_data['goods_id'] = instance.id
                applyment_data['merchant_id'] = merchant_id
                applyment_data['companyuser_id'] = user.id
                applyment_data['level_id'] = user.level_id
                # applyment_data['manufacturer'] = manufacturer
                # applyment_data['specifications'] = specifications
                # applyment_data['is_launched'] = is_launched
                applyment_data['applyment_type'] = 2
                applyment_data['barcode'] = barcode
                applyment_data['create_time'] = datetime.datetime.now()
                GoodsModifyApplyment.objects.create(**applyment_data)
                try:
                    GoodsAuditRecord.objects.create(
                        goods_id=instance.id,
                        create_user_id=user.id,
                        audit_type=1,
                        remark="新增商品"
                    )
                except:
                    pass
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                error_enum = {
                    "name": '商品名称',
                    "caption": '品牌',
                    "desc_detail": '商品介绍',
                    "market_price": '市场价',
                    "default_image": '商品封面图',
                    "manufacturer": '厂商',
                    "specifications": '规格',
                    "remain_stock": '库存',
                    "image": '商品轮播图'
                }
                for key, value in error_enum.items():
                    if key in e:
                        result = f'您输入的{value}有误，请重新输入。'
                        break
                    else:
                        result = f'提交失败,请联系管理员处理。'
                return Response({'error': result}, status=status.HTTP_400_BAD_REQUEST)
        transaction.savepoint_commit(save_id)
        return Response({'success': '提交成功,请耐心等待客服审核生效', 'goods_id': instance.id}, status=status.HTTP_200_OK)

    def sweep_code_identification(self, request):
        barcode = self.request.query_params.get('barcode', None)
        business_no = self.request.query_params.get('business_no', None)
        if not all([barcode, business_no]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not barcode:
            return Response({'error': 'barcode是空格'}, status=status.HTTP_400_BAD_REQUEST)
        if barcode == ' ':
            return Response({'error': 'barcode是空格'}, status=status.HTTP_400_BAD_REQUEST)
        url = f'https://api.jisuapi.com/barcode2/query?appkey=332d5b0000350eb8&barcode={barcode}'
        response = requests.get(url=url)
        result = response.json()
        data = {}
        data['name'] = ''
        data['default_image'] = ''
        data['price'] = ''
        data['sales'] = ''
        data['goodsimage_set'] = []
        data['desc_detail'] = [{
                    "b_title": "商品说明",
                    "arr2": []
                }]
        data['market_price'] = '0.00'
        data['manufacturer'] = ''
        data['specifications'] = ''
        data['stock'] = 0
        data['caption'] = ''
        try:
            if result['status'] == 0:
                result = result['result']
                pic_url = result['pic']
                if 'http' in pic_url:
                    try:
                        img_id = f'youhuiquanyi/{business_no}/goods_image{"%06d" % randint(0, 999999)}.png'
                        mid_img = pic_upload(requests.get(url=pic_url).content, key=img_id)
                        data['default_image'] = f'https://circle.sutpay.cn/{img_id}'
                        data['goodsimage_set'] = [f'https://circle.sutpay.cn/{img_id}']
                        data['desc_detail'] = [{
                            "b_title": "商品说明",
                            "arr2":[{
                                "title": "",
                                "text": "",
                                "img": f'https://circle.sutpay.cn/{img_id}'
                            }]
                        }]
                    except Exception as e:
                        pass
                data['name'] = result['name']
                if result['price']:
                    data['price'] = result['price']
                else:
                    data['price'] = '0.00'
                data['manufacturer'] = result['company']
                data['caption'] = result['brand']
                data['specifications'] = result['type']
            else:
                url = f'https://bff.gds.org.cn/gds/searching-api/ProductService/ProductListByGTIN?PageSize=30&PageIndex=1&SearchItem={barcode}'
                response = requests.get(url=url)
                if response.status_code == 200:
                    pass
        except:
            pass
        return Response(data, status=status.HTTP_200_OK)

    def first_audit(self, request):
        user = self.request.iser
        if user.role_id == 3:
            return Response({'error': '您无权限审核,请联系区县管理员审核'}, status=status.HTTP_400_BAD_REQUEST)
        if user.level.level == 4:
            return Response({'error': '您无权限审核,请联系区县管理员审核'}, status=status.HTTP_400_BAD_REQUEST)
        goods_id = self.request.data.get('goods_id', None)
        audit_state = self.request.data.get('audit_state', None)
        reject_reason = self.request.data.get('reject_reason', None)
        if not goods_id:
            return Response({'error': '请上传商品id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            goods = self.get_queryset().get(id=goods_id)
        except:
            return Response({'error': '无效商品id'}, status=status.HTTP_400_BAD_REQUEST)
        if str(audit_state) not in ['1', '2']:
            return Response({'error': '无效审核参数'}, status=status.HTTP_400_BAD_REQUEST)
        if goods.is_launched != 4:
            return Response({'error': '商品状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(audit_state) == '1':
            goods.is_launched = 2
            goods.save()
            remark = '区县管理员审核商品(通过)'
        else:
            applyment = GoodsModifyApplyment.objects.filter(applyment_type=2, goods_id=goods.id, applyment_status=1).first()
            if applyment:
                applyment.applyment_status = 3
                applyment.reject_reason = reject_reason
                applyment.save()
            goods.is_launched = 3
            goods.save()
            remark = '区县管理员审核商品(驳回)'
        try:
            GoodsAuditRecord.objects.create(
                goods_id=goods.id,
                create_user_id=user.id,
                audit_type=2,
                remark=remark
            )
        except:
            pass
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        if instance.is_launched == 2:
            return Response({'error': '已存在待审核修改单,请耐心等待客服审核'}, status=status.HTTP_400_BAD_REQUEST)
        goods_tag_id = self.request.data.get('goods_tag_id', None)
        if user.role_id == 3:
            is_launched1 = 4
        else:
            is_launched1 = 2
        if not goods_tag_id:
            if not instance.goods_tag:
                return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
            else:
                applyment_data = {}
                applyment_data['create_time'] = datetime.datetime.now()
                applyment_data['goods_id'] = instance.id
                applyment_data['goods_tag'] = instance.goods_tag
                applyment_data['companyuser_id'] = user.id
                applyment_data['level_id'] = user.level_id
                applyment_data['update_word'] = "['goods_tag']"
                applyment, create = GoodsModifyApplyment.objects.get_or_create(goods_id=instance.id, applyment_status=1, defaults=applyment_data)
                instance.goods_tag = None
                instance.is_launched = is_launched1
                instance.save()
        else:
            goods_tag_activity_level = GoodsTagActivityLevelRelation.objects.filter(id=goods_tag_id, level_id=user.level_id).first()
            if not goods_tag_activity_level:
                return Response({'error': '无效标签活动id'}, status=status.HTTP_400_BAD_REQUEST)
            goods_tag = goods_tag_activity_level.goods_tag_activity.goods_tag
            instance.goods_tag = goods_tag
            instance.is_launched = is_launched1
            instance.save()
            applyment_data = {}
            applyment_data['create_time'] = datetime.datetime.now()
            applyment_data['goods_id'] = instance.id
            applyment_data['goods_tag'] = instance.goods_tag
            applyment_data['companyuser_id'] = user.id
            applyment_data['level_id'] = user.level_id
            applyment_data['update_word'] = "['goods_tag']"
            applyment, create = GoodsModifyApplyment.objects.get_or_create(goods_id=instance.id, applyment_status=1, defaults=applyment_data)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class OrderInfoModelViewSet(ModelViewSet):
    '''订单'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('ordergoods__merchant__name', 'ordergoods__goods__name', 'ordergoods__merchant__wyfMerchantID')
    filter_class = OrderInfoFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return OrderInfoListModelSerializer
        else:
            return OrderInfoRetrieveModelSerializer

    def get_queryset(self):
        user = self.request.iser
        # level = user.level
        # level_id = self.request.query_params.get('level', None)
        # if level_id:
        #     try:
        #         level_list = get_level_list(level)
        #         level_id = int(level_id)
        #         if level_id in level_list:
        #             level = Level.objects.filter(id=level_id).first()
        #     except:
        #         pass
        # if level.level == 0:
        #     queryset = OrderInfo.objects.all().order_by('-create_time')
        # elif level.level == 1:
        #     queryset = OrderInfo.objects.filter(level__prov_id=level.id).order_by('-create_time')
        # elif level.level == 2:
        #     queryset = OrderInfo.objects.filter(level__city_id=level.id).order_by('-create_time')
        # elif level.level == 3:
        #     queryset = OrderInfo.objects.filter(level__district_id=level.id).order_by('-create_time')
        # else:
        #     queryset = OrderInfo.objects.filter(level__branch_id=level.id).order_by('-create_time')
        queryset = OrderInfo.objects.filter(level_id=user.level_id, state__in=[3, 2, 12, 9, 6, 8, 5, 14], order_type__in=[1, 4, 5]).exclude(orderNum__contains='vm').order_by('-create_time')
        return queryset

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        wait_count = queryset.filter(state=2).count()
        use_count = queryset.filter(state=3).count()
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['wait_count'] = str(wait_count)
        self.request.data['use_count'] = str(use_count)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def check_coupon(self, request):
        user = self.request.iser
        coupon_id = self.request.data.get('coupon_id', None)
        if not coupon_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        coupon_id = str(coupon_id).replace('https://qrcode.sutpay.com/merchant/coupon/?sn=', '').replace('https://qrcode.sutpay.com/manager/coupon/?sn=', '')
        try:
            goodscoupon = GoodsCoupons.objects.get(coupons_id=coupon_id)
        except:
            return Response({'error': '无效核销码'}, status=status.HTTP_400_BAD_REQUEST)
        order = goodscoupon.order
        goods = goodscoupon.goods
        if goods.category_id != 1:
            return Response({'error': '核销码类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if user.level_id != order.level_id:
            is_can = 0
            try:
                msg = f'*您归属{user.level.name},该订单属于{order.level.name},您没有该商品的核销权限!'
            except:
                msg = f'*您没有该商品的核销权限!'
            coupon_arr = []
            coupon_list = []
        else:
            if goodscoupon.status == 1:
                is_can = 1
                msg = ''
                coupon_arr = [coupon_id]
                coupon_list = []
            else:
                goodscoupons_set = GoodsCoupons.objects.filter(order_id=order.id, status=1).exclude(coupons_id=coupon_id)
                if goodscoupons_set:
                    coupon_arr = []
                    coupon_list = []
                    for goodscoupons in goodscoupons_set:
                        coupon_arr.append(goodscoupons.coupons_id)
                        coupon_list.append({
                            'goods_name': goodscoupons.goods.name,
                            'price': goodscoupons.goods.price,
                            'count': 1
                        })
                    is_can = 2
                    msg = ''
                else:
                    is_can = 0
                    if goodscoupon.status == 3:
                        msg = '**提货码已过期'
                    if goodscoupon.status == 4:
                        msg = '**提货码已撤销'
                    else:
                        msg = ''
                    coupon_arr = []
                    coupon_list = []
        data = {}
        data['merchant_name'] = goods.merchant.managerName
        data['goods_name'] = goods.name
        data['default_image'] = goods.default_image.url
        data['count'] = 1
        data['price'] = goods.price
        data['create_time'] = order.create_time.strftime('%Y-%m-%d %H:%M:%S')
        if order.level:
            data['level_name'] = order.level.name
        else:
            data['level_name'] = '商家自营'
        data['mobile'] = order.reserved_mobile
        data['request_date'] = {'coupon_arr': coupon_arr, 'order_id': order.id}
        data['coupon_list'] = coupon_list
        data['is_can'] = is_can
        data['msg'] = msg
        data['status'] = goodscoupon.status
        data['status_str'] = goodscoupon.get_status_display()
        return Response(data, status=status.HTTP_200_OK)

    def use_coupon(self, request):
        user = self.request.iser
        coupon_arr = self.request.data.get('coupon_arr', None)
        order_id = self.request.data.get('order_id', None)
        if not all([coupon_arr, order_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if type(coupon_arr) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            order = OrderInfo.objects.get(id=order_id)
        except:
            return Response({'error': '无效订单号'}, status=status.HTTP_400_BAD_REQUEST)
        if order.order_type == 3:
            return Response({'error': '此核销码为兑换券类型,请在对应渠道使用'}, status=status.HTTP_400_BAD_REQUEST)
        if order.state != 2:
            return Response({'error': '订单已无未核销商品,请刷新核实'}, status=status.HTTP_400_BAD_REQUEST)
        if order.level_id != user.level_id:
            return Response({'error': '您无权核销该订单'}, status=status.HTTP_400_BAD_REQUEST)
        coupon_arr1 = []
        for coupon_id in coupon_arr:
            coupon_id = str(coupon_id).replace('https://qrcode.sutpay.com/merchant/coupon/?sn=', '').replace('https://qrcode.sutpay.com/manager/coupon/?sn=', '')
            coupon_arr1.append(coupon_id)
        goodscoupons_set = GoodsCoupons.objects.filter(coupons_id__in=coupon_arr1, order_id=order_id, status=1)
        for goodscoupons in goodscoupons_set:
            goodscoupons.status = 2
            goodscoupons.use_time = datetime.datetime.now()
            goodscoupons.use_user_id = user.id
            goodscoupons.save()
        data = {}
        goodscoupons_set = GoodsCoupons.objects.filter(order_id=order_id, status=1)
        if not goodscoupons_set:
            order.state = 3
            order.use_time = datetime.datetime.now()
            order.save()
            if order.order_type in [1, 7]:
                if order.id in [7672020,7672045,7674242,7674956,7675471,7676300,7678324,7678942,7683071,7684871,7684958,7685029,7685069,7685501,7685745,7685834,7686162,7686394,7686427,7686602,7687650,7687715,7687732,7688095,7688100,7688115,7688177,7689635,7690181,7690252,7691071,7691250,7691322,7691521,7691640,7691750,7691902,7691980,7692197,7692322,7692408,7692446,7692523,7692575,7692788,7692893,7692905,7692913,7692928,7692935,7693053,7693232,7693243,7693589,7693754,7693853,7693873,7694060,7694073,7694101,7694630,7695664,7695806,7696083,7696621,7696714,7697092,7697095,7697551,7697859,7697958,7698614,7698646,7698655,7698909,7699082,7699163,7699172,7699564,7699605,7699853,7699887,7699912,7699931,7699964,7700006,7700031,7700047,7700052,7700062,7700075,7700172,7700459,7700584,7700588,7700670,7700721,7700820,7700845,7700976,7700989,7700999,7701002,7701007,7701433,7701589,7701871,7701875,7701887,7701958,7702171,7702268,7702329,7702384,7702446,7702786,7702792,7702819,7702946,7703371,7703612,7703659,7703813,7704351,7709209,7709282,7709476,7710162,7710597,7710673,7710887,7711166,7711406,7711602,7711681,7711682,7712417,7712929,7713026,7713100,7713154,7713233,7713305,7713343,7713450,7713542,7713607,7713661,7713753,7713849,7713969,7713997,7714051,7714177,7714268,7714340,7714390,7714416,7714426,7714454,7714516,7714674,7714934,7714980,7715259,7715316,7715426,7715476,7715609,7715633,7715707,7715874,7716206,7716309,7716397,7716453,7716545,7716631,7716702,7716739,7716773,7716856,7716875,7716937,7717131,7717347,7717543,7717645,7718059,7718326,7718410,7718451,7718664,7718842,7718929,7719030,7719432,7719773,7720213,7720468,7720651,7720748,7720963,7721067,7721402,7721656,7721789,7721976,7722710,7722724,7722986,7723051,7723185,7723279,7723338,7723685,7723731,7723879,7724128,7724277,7724335,7724850,7724905,7725367,7725817,7726083,7726342,7726589,7727145,7727186,7727748,7727997,7728792,7728877,7728961,7729005,7729079,7729139,7730110,7730426,7730606,7730904,7730908,7730916,7730957,7731299,7731841,7733005,7733011,7733169,7733264,7733383,7733487,7733891,7734067,7736407,7737667,7738858,7739080,7739784,7740238,7740418,7740427,7740433,7740473,7740568,7740684,7741374,7741425,7742885,7743504,7743924,7743932,7744208,7744586,7745027,7745078,7745146,7745187,7745226,7745646,7745758,7746549,7746919,7747277,7747706,7747799,7747907,7748140,7748740,7749269,7749301,7749370,7749434,7749707,7749854,7749929,7750622,7750758,7750931,7751148,7752094,7752318,7752335,7752475,7752595,7752871,7752889,7753073,7753301,7753332,7753865,7754008,7754323,7754511,7754592,7754665,7754818,7754821,7754822,7754824,7754825,7754826,7754827,7754834,7754843,7754849,7754858,7754865,7754868,7754871,7754896,7754911,7754913,7754915,7754925,7755425,7756009,7756145]:
                    OrderAdvance.objects.create(
                        order_id=order.id,
                        status=5,
                        remark='客户经理核销订单,记录操作日志',
                        user_id=user.id
                    )
                else:
                    result = ''
                    try:
                        # ordergoods_set = order.ordergoods_set.all().filter(goods__is_settlement=1)
                        # context = ''
                        # for ordergoods in ordergoods_set:
                        #     context = context + f'{ordergoods.goods.name}*{ordergoods.count},'
                        #     receipts_time = datetime.datetime.now().strftime('%Y-%m-%d')
                        #     bill = MerchantBill.objects.filter(receipts_time=receipts_time, merchant_id=ordergoods.merchant_id, bill_type=order.order_species).first()
                        #     if not bill:
                        #         bill_data = {}
                        #         bill_data['merchant_id'] = ordergoods.merchant_id
                        #         bill_data['receipts_time'] = receipts_time
                        #         bill_data['point'] = ordergoods.point
                        #         bill_data['amount'] = ordergoods.price
                        #         bill_data['level_id'] = ordergoods.merchant.level_id
                        #         bill_data['bill_type'] = order.order_species
                        #         bill_data['payable_amount'] = ordergoods.price + Decimal(int(ordergoods.point) / 100)
                        #         bill, create = MerchantBill.objects.get_or_create(defaults=bill_data,
                        #                                                           receipts_time=receipts_time,
                        #                                                           merchant_id=ordergoods.merchant_id, bill_type=order.order_species)
                        #     else:
                        #         bill.point = bill.point + ordergoods.point
                        #         bill.amount = bill.amount + ordergoods.price
                        #         bill.payable_amount = bill.payable_amount + Decimal(int(ordergoods.point) / 100) + ordergoods.price
                        #         bill.save()
                        #     order.payable_settled_amount = order.payable_settled_amount + Decimal(int(ordergoods.point) / 100) + ordergoods.price
                        #     order.bill_id = bill.id
                        #     order.save()
                        # context = context[:-1] + '(支付宝)'
                        # if order.payable_settled_amount:
                        #     body = {
                        #         "shop_id": order.merchant.ruiyinxinMerchantID,
                        #         "shop_order_id": order.order_id,
                        #         "source": "alipay",
                        #         "money": str(order.payable_settled_amount),
                        #         "context": context
                        #     }
                        #     result = ryx_settle_order(body)
                        #     if result['result_code'] == 'success':
                        #         order.bill_order_id = result['order_id']
                        #         order.save()
                        #     else:
                        #         order.bill_error_msg = result['error_msg']
                        #         order.save()
                        if order.is_profit_sharing == 1:
                            out_trade_no = f'{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                            body = {
                                "program_id": "202316837141378884",
                                "shop_id": order.merchant.ruiyinxinMerchantID,
                                "order_id": out_trade_no,
                                "out_trade_no": order.orderNum,
                                "is_profit": "0"
                            }
                            result = ryx_profitsharing_order(body)
                            profitorder = OrderProfitSharing.objects.filter(order_id=order.id).first()
                            if not profitorder:
                                profitorder, create = OrderProfitSharing.objects.get_or_create(defaults={'order_id': order.id, "out_trade_no": out_trade_no}, order_id=order.id)
                            if result['result_code'] == 'success':
                                order.is_profit_sharing = 2
                                order.save()
                                profitorder.profit_order_id = result['profit_order_id']
                                profitorder.profit_time = datetime.datetime.now()
                                profitorder.save()
                                OrderAdvance.objects.create(
                                    order_id=order.id,
                                    status=5,
                                    remark='客户经理核销订单,解冻资金',
                                    user_id=user.id
                                )
                                receipts_time = datetime.datetime.now().strftime('%Y-%m-%d')
                                bill = MerchantBill.objects.filter(receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species).first()
                                if not bill:
                                    bill_data = {}
                                    bill_data['merchant_id'] = order.merchant_id
                                    bill_data['receipts_time'] = receipts_time
                                    bill_data['amount'] = order.total_price
                                    bill_data['commission'] = order.freight
                                    bill_data['level_id'] = order.merchant.level_id
                                    bill_data['payable_amount'] = order.total_price - order.freight
                                    bill_data['channel_id'] = 3
                                    bill_data['bill_type'] = order.order_species
                                    bill, create = MerchantBill.objects.get_or_create(defaults=bill_data, receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species)
                                else:
                                    bill.amount = bill.amount + order.total_price
                                    bill.commission = bill.commission + order.freight
                                    bill.payable_amount = bill.payable_amount + order.total_price - order.freight
                                    bill.save()
                                order.payable_settled_amount = order.total_price - order.freight
                                order.bill_id = bill.id
                                order.save()
                            else:
                                order.is_profit_sharing = 2
                                order.save()
                                profitorder.error_msg = result['error_msg']
                                profitorder.profit_status = 2
                                profitorder.save()
                                OrderAdvance.objects.create(
                                    order_id=order.id,
                                    status=4,
                                    remark='客户经理核销订单,解冻资金出错',
                                    user_id=user.id
                                )
                        elif order.is_profit_sharing == 3:
                            out_trade_no = f'{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                            body = {
                                "program_id": "202316837141378884",
                                "shop_id": order.merchant.ruiyinxinMerchantID,
                                "order_id": out_trade_no,
                                "out_trade_no": order.orderNum,
                                "is_profit": "2"
                            }
                            result = ryx_profitsharing_order(body)
                            profitorder = OrderProfitSharing.objects.filter(order_id=order.id).first()
                            if not profitorder:
                                profitorder, create = OrderProfitSharing.objects.get_or_create(defaults={'order_id': order.id, "out_trade_no": out_trade_no}, order_id=order.id)
                            if result['result_code'] == 'success':
                                order.is_profit_sharing = 4
                                order.save()
                                profitorder.profit_order_id = result['profit_order_id']
                                profitorder.profit_time = datetime.datetime.now()
                                profitorder.save()
                                OrderAdvance.objects.create(
                                    order_id=order.id,
                                    status=5,
                                    remark='客户经理核销订单,解冻资金',
                                    user_id=user.id
                                )
                                receipts_time = datetime.datetime.now().strftime('%Y-%m-%d')
                                bill = MerchantBill.objects.filter(receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species).first()
                                if not bill:
                                    bill_data = {}
                                    bill_data['merchant_id'] = order.merchant_id
                                    bill_data['receipts_time'] = receipts_time
                                    bill_data['amount'] = order.total_price
                                    bill_data['commission'] = order.freight
                                    bill_data['level_id'] = order.merchant.level_id
                                    bill_data['payable_amount'] = order.total_price - order.freight
                                    bill_data['channel_id'] = 3
                                    bill_data['bill_type'] = order.order_species
                                    bill, create = MerchantBill.objects.get_or_create(defaults=bill_data, receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species)
                                else:
                                    bill.amount = bill.amount + order.total_price
                                    bill.commission = bill.commission + order.freight
                                    bill.payable_amount = bill.payable_amount + order.total_price - order.freight
                                    bill.save()
                                order.payable_settled_amount = order.total_price - order.freight
                                order.bill_id = bill.id
                                order.save()
                            else:
                                order.is_profit_sharing = 4
                                order.save()
                                profitorder.error_msg = result['error_msg']
                                profitorder.profit_status = 2
                                profitorder.save()
                                OrderAdvance.objects.create(
                                    order_id=order.id,
                                    status=4,
                                    remark='客户经理核销订单,解冻资金出错',
                                    user_id=user.id
                                )
                    except Exception as e:
                        logger.error(e)
                        OrderAdvance.objects.create(
                            order_id=order.id,
                            status=4,
                            remark=f'商户自行核销订单,解冻资金出错,微邮付接口{result}',
                            merchantuser_id=user.id
                        )
        coupon_arr = []
        coupon_list = []
        for goodscoupons in goodscoupons_set:
            coupon_arr.append(goodscoupons.coupons_id)
            coupon_list.append({
                'goods_name': goodscoupons.goods.name,
                'price': goodscoupons.goods.price,
                'count': 1
            })
        data['request_date'] = {'coupon_arr': coupon_arr, 'order_id': order.id}
        data['coupon_list'] = coupon_list
        return Response(data, status=status.HTTP_200_OK)


class AliDiscountCouponLevelModelViewSet(ModelViewSet):
    '''支付宝活动'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('activity__activity_name', )
    filter_class = AliDiscountCouponLevelFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        date_now = datetime.datetime.now()
        # level_id = self.request.query_params.get('level', None)
        # if level_id:
        #     try:
        #         level_list = get_level_list(level)
        #         level_id = int(level_id)
        #         if level_id in level_list:
        #             level = Level.objects.filter(id=level_id).first()
        #     except:
        #         pass
        # if level.level == 0:
        #     queryset = AliDiscountCouponLevel.objects.all().order_by('-id')
        # elif level.level == 1:
        #     queryset = AliDiscountCouponLevel.objects.filter(level__prov_id=level.id).order_by('-id')
        # elif level.level == 2:
        #     queryset = AliDiscountCouponLevel.objects.filter(level__city_id=level.id).order_by('-id')
        # elif level.level == 3:
        #     queryset = AliDiscountCouponLevel.objects.filter(level__district_id=level.id).order_by('-id')
        # else:
        #     queryset = AliDiscountCouponLevel.objects.filter(level__branch_id=level.id).order_by('-id')
        queryset = AliDiscountCouponLevel.objects.filter(level_id=level.id, activity__coupon_way__in=[1, 4], activity__publish_start_time__lte=date_now, activity__publish_end_time__gte=date_now, activity__distribution_platform_id=1).order_by('-activity__id')
        return queryset.exclude(activity__coupon_status__in=[2, 4])

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponLevelListModelSerializer
        else:
            return AliDiscountCouponLevelRetrieveModelSerializer

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        activity = instance.activity
        serializer = AliDiscountCouponLevelRetrieveModelSerializer(instance, context={'activity': activity})
        return Response(serializer.data)

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        activity = instance.activity
        if activity.coupon_way == 4:
            if not instance.is_auth:
                return Response({'error': '您无权限派发此活动'}, status=status.HTTP_400_BAD_REQUEST)
            if activity.remain_number <= 0:
                return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            if instance.remain_number <= 0:
                return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.coupon_status != 1:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            channelcommonvoucher = activity.alidiscountcouponchannelcommonvoucher
            if channelcommonvoucher.distributed_limit_by_time == 1:
                week = str(datetime.datetime.now().weekday())
                enable_time = datetime.datetime.now().strftime('1970-01-01 %H:%M:%S')
                alidiscountcoupondstributedlimit = AliDiscountCouponDistributedLimit.objects.filter(
                    ali_discount_coupon_common_voucher_id=channelcommonvoucher.id, weeks__contains=week,
                    start_enable_time__lte=enable_time, end_enable_time__gte=enable_time)
                if not alidiscountcoupondstributedlimit:
                    return Response({'error': '当前时间未在活动派发时间'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            pass
        if activity.max_number_by_day:
            begin_time = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
            end_time = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
            max_no = AliDiscountCouponInfo.objects.filter(alidiscountcoupon_id=activity.id, gmt_create__gte=begin_time, gmt_create__lte=end_time).count()
            if max_no >= activity.max_number_by_day:
                return Response({'error': '今天的优惠券已派发完毕，请次日参与！'}, status=status.HTTP_400_BAD_REQUEST)
        discountcouponqrcodedata = {}
        identify = random_str()
        if activity.drawdown_platform_id == 3:
            common_url = f'https://qrcode.sutpay.com/business/coupon/?identify={identify}'
        else:
            common_url = f'https://api.sutpay.com/customer/coupon/?identify={identify}'
        common_qrcode = f'youhuiquanyi/coupon/{identify}.png'
        common_qrcode_url = make_qrcode(identify, common_url, common_qrcode)
        discountcouponqrcodedata['identify'] = identify
        discountcouponqrcodedata['common_qrcode'] = common_qrcode
        discountcouponqrcodedata['common_url'] = common_url
        discountcouponqrcodedata['companyuser_id'] = user.id
        discountcouponqrcodedata['alidiscountcoupon_level_id'] = instance.id
        discountcouponqrcodedata['gmt_distributed'] = datetime.datetime.now()
        if activity.coupon_channel != 5:
            out_biz_no = f'100003{str(datetime.datetime.now()).replace("-", "").replace(":", "").replace(" ", "").replace(".", "")}{"%06d" % randint(0, 999999)}'
        else:
            out_biz_no = f'{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{"%04d" % randint(0, 9999)}'
        discountcouponqrcodedata['out_biz_no'] = out_biz_no
        discountcouponqrcodedata, create = AliDiscountCouponQRCode.objects.get_or_create(defaults=discountcouponqrcodedata, identify=identify)
        data = AliDiscountCouponLevelRetrieveModelSerializer(instance, context={'activity': activity}).data
        data['common_qrcode'] = discountcouponqrcodedata.common_qrcode.url
        data['coupon_type'] = activity.coupon_type
        data['coupon_type_str'] = activity.get_coupon_type_display()
        return Response(data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        mobile = self.request.data.get('mobile', None)
        user = self.request.iser
        if not mobile:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.coupon_status != 1:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.coupon_way == 4:
            if not instance.is_auth:
                return Response({'error': '您无权限派发此活动'}, status=status.HTTP_400_BAD_REQUEST)
            if activity.remain_number <= 0:
                return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            if instance.remain_number <= 0:
                return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.max_number_by_day:
            begin_time = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
            end_time = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
            max_no = AliDiscountCouponInfo.objects.filter(alidiscountcoupon_id=activity.id, gmt_create__gte=begin_time, gmt_create__lte=end_time).exclude(status=13).count()
            if max_no >= activity.max_number_by_day:
                return Response({'error': '今天的优惠券已领取完毕，请明天0点继续参与，感谢您对本活动的支持！'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.max_number_by_user:
            max_no = AliDiscountCouponInfo.objects.filter(alidiscountcoupon_id=activity.id, mobile=mobile).exclude(status=13).count()
            if max_no >= activity.max_number_by_user:
                return Response({'error': '用户参与活动次数已达上限，感谢您对本活动的支持！'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.drawdown_platform_id == 3:
            return Response({'error': '当前活动不支持登记派发！'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.is_check_identity == 1:
            check_manager = User.objects.filter(mobile=mobile, is_active=1)
            if check_manager:
                return Response({'error': '该活动暂不允许内部员工领取，如有疑问请咨询客服。'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            channelcommonvoucher = activity.alidiscountcouponchannelcommonvoucher
            if channelcommonvoucher.distributed_limit_by_time == 1:
                week = str(datetime.datetime.now().weekday())
                enable_time = datetime.datetime.now().strftime('1970-01-01 %H:%M:%S')
                alidiscountcoupondstributedlimit = AliDiscountCouponDistributedLimit.objects.filter(
                    ali_discount_coupon_common_voucher_id=channelcommonvoucher.id, weeks__contains=week,
                    start_enable_time__lte=enable_time, end_enable_time__gte=enable_time)
                if not alidiscountcoupondstributedlimit:
                    return Response({'error': '当前时间未在活动派发时间'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            pass
        customeruser = CustomerUser.objects.filter(mobile=mobile).first()
        instance_id = instance.id
        activity_id = activity.id
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                if activity.coupon_way == 4:
                    while True:
                        activity = AliDiscountCoupon.objects.get(id=activity_id)
                        if activity.remain_number <= 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
                        activity_origin_send_count = activity.send_count
                        activity_origin_remain_number = activity.remain_number
                        activity_new_send_count = activity_origin_send_count + 1
                        activity_new_remain_number = activity_origin_remain_number - 1
                        result = AliDiscountCoupon.objects.filter(id=activity_id,send_count=activity_origin_send_count).update(send_count=activity_new_send_count, remain_number=activity_new_remain_number)
                        if result == 0:
                            continue
                        break
                    while True:
                        instance = AliDiscountCouponLevel.objects.get(id=instance_id)
                        instance_origin_take_number = instance.take_number
                        instance_origin_max_number = instance.max_number
                        instance_origin_p_take_number = instance.p_take_number
                        instance_origin_p_max_number = instance.p_max_number
                        instance_new_take_number = instance_origin_take_number + 1
                        instance_new_max_number = instance_origin_max_number + 1
                        instance_new_p_take_number = instance_origin_p_take_number + 1
                        instance_new_p_max_number = instance_origin_p_max_number + 1
                        result = AliDiscountCouponLevel.objects.filter(id=instance_id, take_number=instance_origin_take_number).update(
                            take_number=instance_new_take_number,
                            max_number=instance_new_max_number,
                            p_take_number=instance_new_p_take_number,
                            p_max_number=instance_new_p_max_number
                        )
                        if result == 0:
                            continue
                        break
                    try:
                        relation_set = instance.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_take_number += 1
                            parent.p_max_number += 1
                            parent.save()
                    except:
                        pass
                else:
                    while True:
                        instance = AliDiscountCouponLevel.objects.get(id=instance_id)
                        if instance.remain_number <= 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
                        instance_origin_take_number = instance.take_number
                        instance_origin_remain_number = instance.remain_number
                        instance_origin_p_take_number = instance.p_take_number
                        instance_origin_p_remain_number = instance.p_remain_number
                        instance_new_take_number = instance_origin_take_number + 1
                        instance_new_remain_number = instance_origin_remain_number - 1
                        instance_new_p_take_number = instance_origin_p_take_number + 1
                        instance_new_p_remain_number = instance_origin_p_remain_number - 1
                        result = AliDiscountCouponLevel.objects.filter(id=instance_id, take_number=instance_origin_take_number).update(
                            take_number=instance_new_take_number,
                            remain_number=instance_new_remain_number,
                            p_take_number=instance_new_p_take_number,
                            p_remain_number=instance_new_p_remain_number
                        )
                        if result == 0:
                            continue
                        break
                    try:
                        relation_set = instance.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_take_number += 1
                            parent.p_remain_number -= 1
                            parent.save()
                    except:
                        pass
                    while True:
                        activity = AliDiscountCoupon.objects.get(id=activity_id)
                        activity_origin_send_count = activity.send_count
                        activity_origin_remain_number = activity.remain_number
                        activity_new_send_count = activity_origin_send_count + 1
                        activity_new_remain_number = activity_origin_remain_number - 1
                        result = AliDiscountCoupon.objects.filter(id=activity_id, send_count=activity_origin_send_count).update(
                            send_count=activity_new_send_count,
                            remain_number=activity_new_remain_number
                        )
                        if result == 0:
                            continue
                        break
                alidiscountcouponinfo_data = {}
                alidiscountcouponinfo_data['alidiscountcoupon_id'] = activity.id
                alidiscountcouponinfo_data['alidiscountcoupon_level_id'] = instance.id
                alidiscountcouponinfo_data['level_id'] = instance.level_id
                alidiscountcouponinfo_data['status'] = 0
                alidiscountcouponinfo_data['template_id'] = activity.template_id
                if activity.coupon_channel != 5:
                    out_biz_no = f'100004{str(datetime.datetime.now()).replace("-", "").replace(":", "").replace(" ", "").replace(".", "")}{"%06d" % randint(0, 999999)}'
                else:
                    out_biz_no = f'{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{"%04d" % randint(0, 9999)}'
                alidiscountcouponinfo_data['out_biz_no'] = out_biz_no
                alidiscountcouponinfo_data['mobile'] = mobile
                alidiscountcouponinfo_data['companyuser_id'] = user.id
                alidiscountcouponinfo_data['gmt_distributed'] = datetime.datetime.now()
                alidiscountcouponinfo_data['coupon_channel'] = activity.coupon_channel
                if customeruser:
                    alidiscountcouponinfo_data['customer_user_id'] = customeruser.id
                alidiscountcouponinfo, crete = AliDiscountCouponInfo.objects.get_or_create(defaults=alidiscountcouponinfo_data, out_biz_no=out_biz_no)
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '派发失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '派发成功', 'couponinfo_id': alidiscountcouponinfo.id}, status=status.HTTP_200_OK)

    def distributed_statistical(self, request):
        coupon_id = self.request.query_params.get('coupon_id', None)
        dimensionality = self.request.query_params.get('dimensionality', '3')
        sort = self.request.query_params.get('sort', '0')
        user = self.request.iser
        level_level_id = user.level.level
        if not coupon_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=coupon_id)
            activity = instance.activity
        except:
            return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
        if level_level_id not in [0, 1, 2] and dimensionality == '1':
            return Response({'error': '当前客户经理等级不能查看市级数据统计'}, status=status.HTTP_400_BAD_REQUEST)
        if level_level_id not in [0, 1, 2, 3] and dimensionality == '2':
            return Response({'error': '当前客户经理等级不能查看区县级数据统计'}, status=status.HTTP_400_BAD_REQUEST)
        if dimensionality == '1':
            queryset = AliDiscountCouponLevel.objects.filter(level__level=2, child_set__parent_id=instance.id)
        elif dimensionality == '2':
            queryset = AliDiscountCouponLevel.objects.filter(level__level=3, child_set__parent_id=instance.id)
        else:
            queryset = AliDiscountCouponLevel.objects.filter(level__level=4, child_set__parent_id=instance.id)
        if sort == '0':
            queryset = queryset.order_by('p_max_number', 'id')
        elif sort == '1':
            queryset = queryset.order_by('-p_max_number', 'id')
        elif sort == '2':
            queryset = queryset.order_by('p_take_number', 'id')
        elif sort == '3':
            queryset = queryset.order_by('-p_take_number', 'id')
        elif sort == '4':
            queryset = queryset.order_by('p_use_number', 'id')
        elif sort == '5':
            queryset = queryset.order_by('-p_use_number', 'id')
        elif sort == '6':
            queryset = queryset.order_by(F('p_take_number') / F('p_max_number'), 'id')
        elif sort == '7':
            queryset = queryset.order_by(-F('p_take_number') / F('p_max_number'), 'id')
        elif sort == '8':
            queryset = queryset.order_by(F('p_remain_number') / F('p_max_number'), 'id')
        elif sort == '9':
            queryset = queryset.order_by(-F('p_remain_number') / F('p_max_number'), 'id')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = AliDiscountCouponLevelStatisticalModelSerializer(page, many=True, context={'activity': activity})
            return self.get_paginated_response(serializer.data)
        serializer = AliDiscountCouponLevelStatisticalModelSerializer(queryset, many=True, context={'activity': activity})
        return Response(serializer.data)


class AliDiscountCouponInfoModelViewSet(ModelViewSet):
    '''券信息'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = AliDiscountCouponInfoFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponInfoListModelSerializer
        else:
            return AliDiscountCouponInfoRetrieveModelSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        coupon_id = self.request.query_params.get('coupon_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        if not coupon_id:
            if level.level == 0:
                queryset = AliDiscountCouponInfo.objects.all().order_by('-id')
            elif level.level == 1:
                queryset = AliDiscountCouponInfo.objects.filter(level__prov_id=level.id).order_by('-id')
            elif level.level == 2:
                queryset = AliDiscountCouponInfo.objects.filter(level__city_id=level.id).order_by('-id')
            elif level.level == 3:
                queryset = AliDiscountCouponInfo.objects.filter(level__district_id=level.id).order_by('-id')
            else:
                queryset = AliDiscountCouponInfo.objects.filter(level__branch_id=level.id).order_by('-id')
            self.request.data['acitivty_info'] = {}
        else:
            try:
                couponlevel = AliDiscountCouponLevel.objects.get(id=coupon_id)
                self.request.data['acitivty_info'] = AliDiscountCouponLevelListModelSerializer(couponlevel).data
                if level.level == 0:
                    queryset = AliDiscountCouponInfo.objects.filter(alidiscountcoupon_id=couponlevel.activity_id).order_by('-id')
                elif level.level == 1:
                    queryset = AliDiscountCouponInfo.objects.filter(level__prov_id=level.id, alidiscountcoupon_id=couponlevel.activity_id).order_by('-id')
                elif level.level == 2:
                    queryset = AliDiscountCouponInfo.objects.filter(level__city_id=level.id, alidiscountcoupon_id=couponlevel.activity_id).order_by('-id')
                elif level.level == 3:
                    queryset = AliDiscountCouponInfo.objects.filter(level__district_id=level.id, alidiscountcoupon_id=couponlevel.activity_id).order_by('-id')
                else:
                    queryset = AliDiscountCouponInfo.objects.filter(level__branch_id=level.id, alidiscountcoupon_id=couponlevel.activity_id).order_by('-id')
            except:
                if level.level == 0:
                    queryset = AliDiscountCouponInfo.objects.all().order_by('-id')
                elif level.level == 1:
                    queryset = AliDiscountCouponInfo.objects.filter(level__prov_id=level.id).order_by('-id')
                elif level.level == 2:
                    queryset = AliDiscountCouponInfo.objects.filter(level__city_id=level.id).order_by('-id')
                elif level.level == 3:
                    queryset = AliDiscountCouponInfo.objects.filter(level__district_id=level.id).order_by('-id')
                else:
                    queryset = AliDiscountCouponInfo.objects.filter(level__branch_id=level.id).order_by('-id')
        return queryset

    # def list(self, request, *args, **kwargs):
    #     coupon_id = self.request.query_params.get('coupon_id', None)
    #     try:
    #         if '_mutable' in self.request.data.__dict__:
    #             self.request.data.__dict__['_mutable'] = True
    #     except:
    #         pass
    #     if coupon_id:
    #         try:
    #             couponlevel = AliDiscountCouponLevel.objects.get(id=coupon_id)
    #             self.request.data['acitivty_info'] = AliDiscountCouponLevelListModelSerializer(couponlevel).data
    #         except:
    #             pass
    #     else:
    #         self.request.data['acitivty_info'] = {}
    #     return super().list(request, *args, **kwargs)
    
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.status != 0:
            return Response({'error': '当前代金券状态无法撤销'}, status=status.HTTP_400_BAD_REQUEST)
        alidiscountcoupon_level_id = instance.alidiscountcoupon_level_id
        activity = instance.alidiscountcoupon
        activity_id = activity.id
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                instance.status = 13
                instance.gmt_undo = datetime.datetime.now()
                instance.save()
                if activity.coupon_way == 4:
                    while True:
                        alidiscountcoupon_level = AliDiscountCouponLevel.objects.get(id=alidiscountcoupon_level_id)
                        instance_origin_take_number = alidiscountcoupon_level.take_number
                        instance_origin_max_number = alidiscountcoupon_level.max_number
                        instance_origin_p_take_number = alidiscountcoupon_level.p_take_number
                        instance_origin_p_max_number = alidiscountcoupon_level.p_max_number
                        instance_new_take_number = instance_origin_take_number - 1
                        instance_new_max_number = instance_origin_max_number - 1
                        instance_new_p_take_number = instance_origin_p_take_number - 1
                        instance_new_p_max_number = instance_origin_p_max_number - 1
                        result = AliDiscountCouponLevel.objects.filter(id=alidiscountcoupon_level_id,
                                                                       take_number=instance_origin_take_number).update(
                            take_number=instance_new_take_number,
                            max_number=instance_new_max_number,
                            p_take_number=instance_new_p_take_number,
                            p_max_number=instance_new_p_max_number
                        )
                        if result == 0:
                            continue
                        break
                    while True:
                        activity = AliDiscountCoupon.objects.get(id=activity_id)
                        activity_origin_send_count = activity.send_count
                        activity_origin_remain_number = activity.remain_number
                        activity_new_send_count = activity_origin_send_count - 1
                        activity_new_remain_number = activity_origin_remain_number + 1
                        result = AliDiscountCoupon.objects.filter(id=activity_id,send_count=activity_origin_send_count).update(
                            send_count=activity_new_send_count,
                            remain_number=activity_new_remain_number
                        )
                        if result == 0:
                            continue
                        break
                    try:
                        relation_set = alidiscountcoupon_level.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_take_number -= 1
                            parent.p_max_number -= 1
                            parent.save()
                    except:
                        pass
                else:
                    while True:
                        alidiscountcoupon_level = AliDiscountCouponLevel.objects.get(id=alidiscountcoupon_level_id)
                        instance_origin_take_number = alidiscountcoupon_level.take_number
                        instance_origin_remain_number = alidiscountcoupon_level.remain_number
                        instance_origin_p_take_number = alidiscountcoupon_level.p_take_number
                        instance_origin_p_remain_number = alidiscountcoupon_level.p_remain_number
                        instance_new_take_number = instance_origin_take_number - 1
                        instance_new_remain_number = instance_origin_remain_number + 1
                        instance_new_p_take_number = instance_origin_p_take_number - 1
                        instance_new_p_remain_number = instance_origin_p_remain_number + 1
                        result = AliDiscountCouponLevel.objects.filter(id=alidiscountcoupon_level_id, take_number=instance_origin_take_number).update(
                            take_number=instance_new_take_number,
                            remain_number=instance_new_remain_number,
                            p_take_number=instance_new_p_take_number,
                            p_remain_number=instance_new_p_remain_number
                        )
                        if result == 0:
                            continue
                        break
                    while True:
                        activity = AliDiscountCoupon.objects.get(id=activity_id)
                        activity_origin_send_count = activity.send_count
                        activity_origin_remain_number = activity.remain_number
                        activity_new_send_count = activity_origin_send_count - 1
                        activity_new_remain_number = activity_origin_remain_number + 1
                        result = AliDiscountCoupon.objects.filter(id=activity_id, send_count=activity_origin_send_count).update(
                            send_count=activity_new_send_count,
                            remain_number=activity_new_remain_number
                        )
                        if result == 0:
                            continue
                        break
                    try:
                        relation_set = alidiscountcoupon_level.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_take_number -= 1
                            parent.p_remain_number += 1
                            parent.save()
                    except:
                        pass
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '撤销失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '撤销成功,额度已经释放,可重新派发'}, status=status.HTTP_200_OK)


class AliDiscountCouponMerchantModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = AliDiscountCouponMerchantFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'merchant__wyfMerchantID', 'sub_mchid')

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = AliDiscountCouponMerchant.objects.filter().exclude(merchant_id__isnull=True)
        elif level.level == 1:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__prov_id=level.id).exclude(merchant_id__isnull=True)
        elif level.level == 2:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__city_id=level.id).exclude(merchant_id__isnull=True)
        elif level.level == 3:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__district_id=level.id).exclude(merchant_id__isnull=True)
        else:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__branch_id=level.id).exclude(merchant_id__isnull=True)
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['last_update_time'] = '2025-03-04 00:23:58'
        return queryset

    def get_serializer_class(self):
        return AliDiscountCouponMerchantModelSerializer


class ExemptAliDiscountCouponModelViewSet(ModelViewSet):

    def create(self, request, *args, **kwargs):
        data = self.request.data
        activity_name = data.get('activity_name', None)
        comment = data.get('comment', None)
        available_begin_time = data.get('available_begin_time', None)
        available_end_time = data.get('available_end_time', None)
        max_coupons = data.get('max_coupons', None)
        description = data.get('description', None)
        max_coupons_per_user = data.get('max_coupons_per_user', None)
        coupon_amount = data.get('coupon_amount', None)
        transaction_minimum = data.get('transaction_minimum', None)
        coupon_channel = data.get('coupon_channel', None)
        merchant_id_arr = data.get('merchant_id_arr', None)
        if not all([activity_name, available_begin_time, available_end_time, max_coupons, max_coupons_per_user,
                    coupon_amount, transaction_minimum, coupon_channel, merchant_id_arr]):
            return Response({'error': '缺少必传参数'})
        try:
            begin_time = time.strptime(str(available_begin_time), "%Y-%m-%d")
            end_time = time.strptime(str(available_end_time), "%Y-%m-%d")
        except:
            return Response({'error': '活动时间格式出错'}, status=status.HTTP_400_BAD_REQUEST)
        if begin_time < time.strptime(datetime.datetime.now().strftime('%Y-%m-%d'), "%Y-%m-%d"):
            return Response({'error': '活动开始时间不能小于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
        if end_time < time.strptime(datetime.datetime.now().strftime('%Y-%m-%d'), "%Y-%m-%d"):
            return Response({'error': '活动结束时间不能小于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
        if begin_time < end_time:
            return Response({'error': '活动开始时间不能大于结束时间'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            max_coupons = int(max_coupons)
            max_coupons_per_user = int(max_coupons_per_user)
            coupon_amount = Decimal(str(coupon_amount))
            transaction_minimum = Decimal(str(transaction_minimum))
            max_amount = max_coupons * coupon_amount
        except:
            return Response({'error': '请输入正确的数字格式'}, status=status.HTTP_400_BAD_REQUEST)
        if type(merchant_id_arr) != list:
            return Response({'error': '商户'}, status=status.HTTP_400_BAD_REQUEST)
        if coupon_amount >= transaction_minimum:
            return Response({'error': '使用门槛不得低于优惠面额!'}, status=status.HTTP_400_BAD_REQUEST)
        if not description:
            description = f'1、本券不可兑换现金，不可找零。\n2、每个用户最多可以领取{max_coupons_per_user}张。'
        if str(coupon_channel) == '1':
            pass
        elif str (coupon_channel) == '2':
            pass


class ActivityLevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('activity__name', )
    filter_class = ActivityLevelFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        today = datetime.datetime.now()
        queryset = ActivityLevel.objects.filter(level_id=level.id, activity__available_begin_time__lte=today, activity__available_end_time__gte=today).order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return ActivityLevelListModelSerializer
        else:
            return ActivityLevelRetrieveModelSerializer

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        point = self.request.data.get('point', None)
        if not point:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            point = Decimal(int(point))
        except:
            return Response({'error': '请输入正整数'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.remain_point < point:
            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.activity_state != 2:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        date_now = datetime.datetime.now()
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                instance_id = instance.id
                activity_id = activity.id
                while True:
                    instance = ActivityLevel.objects.get(id=instance_id)
                    activity = Activity.objects.get(id=activity_id)
                    origin_take_point = instance.take_point
                    origin_remain_point = instance.remain_point
                    origin_p_take_point = instance.p_take_point
                    origin_p_remain_point = instance.p_remain_point
                    if origin_remain_point < point:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
                    new_take_point = origin_take_point + point
                    new_remain_point = origin_remain_point - point
                    new_p_take_point = origin_p_take_point + point
                    new_p_remain_point = origin_p_remain_point - point
                    result = ActivityLevel.objects.filter(id=instance_id, take_point=origin_take_point, remain_point=origin_remain_point,
                                                          p_take_point=origin_p_take_point, p_remain_point=origin_remain_point).update(
                        take_point=new_take_point, remain_point=new_remain_point, p_take_point=new_p_take_point, p_remain_point=new_p_remain_point
                    )
                    activity_origin_take_point = activity.take_point
                    activity_origin_remain_point = activity.remain_point
                    activity_new_take_point = activity_origin_take_point + point
                    activity_new_remain_point = activity_origin_remain_point - point
                    result1 = Activity.objects.filter(id=activity_id, take_point=activity_origin_take_point, remain_point=activity_origin_remain_point).update(
                        take_point=activity_new_take_point, remain_point=activity_new_remain_point
                    )
                    if result == 0 or result1 == 0:
                        continue
                    relation_set = instance.child_set.all()
                    for relation in relation_set:
                        parent = relation.parent
                        parent.p_take_point += 1
                        parent.p_remain_point -= 1
                        parent.save()
                    break
                activity_data = {}
                activity_data['activity_data_id'] = timezone.now().strftime('%Y%m%d%H%M%S') + ('%06d' % randint(0, 999999)) + ('%09d' % user.id)
                activity_data['point'] = point
                activity_data['remain_point'] = point
                activity_data['create_time'] = date_now
                activity_data['activity_id'] = activity.id
                activity_data['level_id'] = user.level_id
                activity_data['state'] = 1
                activity_data['companyuser_id'] = user.id
                activity_data['activity_level_id'] = instance.id
                identify = random_str()
                common_url = f'https://api.sutpay.com/customer/point/?identify={identify}'
                common_qrcode = f'youhuiquanyi/activity/{identify}.png'
                common_qrcode_url = make_qrcode(identify, common_url, common_qrcode)
                activity_data['identify'] = identify
                activity_data['common_qrcode'] = common_qrcode
                activity_data['common_url'] = common_url
                activity_data['expired_time'] = date_now + datetime.timedelta(minutes=10)
                activity_dat, create = ActivityData.objects.get_or_create(defaults=activity_data, identify=identify)
                if not create:
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '活动剩余邮米发生变化,请刷新重试'}, status=status.HTTP_400_BAD_REQUEST)
                activity_level_record_data = {}
                activity_level_record_data['point'] = point
                activity_level_record_data['operation_type'] = 5
                activity_level_record_data['activity_level_id'] = instance.id
                activity_level_record_data['remain_point'] = new_remain_point
                activity_level_record_data['user_id'] = user.id
                activity_level_record_data['create_time'] = date_now
                activity_level_record_data['level_id'] = user.level_id
                activity_level_record_data['remark'] = '派发邮米'
                activity_level_record_data['activity_data_id'] = activity_dat.id
                ActivityLevelRecord.objects.create(**activity_level_record_data)
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '活动剩余邮米发生变化,请刷新重试'}, status=status.HTTP_400_BAD_REQUEST)
        transaction.savepoint_commit(save_id)
        data = ActivityLevelRetrieveModelSerializer(instance).data
        data['common_qrcode'] = activity_dat.common_qrcode.url
        data['expired_time'] = activity_dat.expired_time.strftime("%Y.%m.%d %H:%M:%S")
        point = str(int(activity_dat.point))
        if len(point) >= 3:
            point = f'{point[:-2]},{point[-2:]}'
        data['point'] = point
        eta = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
        detection_activity_qrcode.apply_async(({"activityqrcode_id": activity_dat.id},), eta=eta)
        return Response(data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        goods_array = self.request.data.get('goods_array', None)
        idcode = self.request.data.get('idcode', None)
        realname = self.request.data.get('realname', None)
        mobile = self.request.data.get('mobile', None)
        sms_code = self.request.data.get('sms_code', None)
        customeruser_id = self.request.data.get('customeruser_id', None)
        if not goods_array:
            return Response({'error': '缺少商品信息'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.activity_state != 2:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            total_point = Decimal('0')
            total_count = 0
            total_price = Decimal('0')
            for goods_data in goods_array:
                goods = Goods.objects.get(id=goods_data['goods_id'])
                if goods.is_use_point == 0:
                    return Response({'error': '选择商品不支持邮米支付'}, status=status.HTTP_400_BAD_REQUEST)
                total_price += Decimal(int(goods_data['count'])) * goods.price
                total_point += Decimal(int(goods_data['count'])) * 100 * goods.price
                total_count += Decimal(int(goods_data['count']))
            merchant_id = goods.merchant_id
            order_type = goods.order_type
        except:
            return Response({'error': '无效商品id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.remain_point < total_point:
            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        if all([idcode, realname, mobile, sms_code]):
            if not re.match(r'^1[3-9]\d{9}$', mobile):
                return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
            if len(idcode) != 18:
                return Response({'error': '身份证格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            redis_conn = get_redis_connection("verify_code")
            sms_code_server = redis_conn.get("sms_%s" % mobile)
            if sms_code_server is None:
                return Response({'error': "短信验证码失效"}, status=status.HTTP_400_BAD_REQUEST)
            sms_code_server = sms_code_server.decode()
            if sms_code_server != str(sms_code):
                return Response({'error': "输入验证码有误"}, status=status.HTTP_400_BAD_REQUEST)
            redis_conn.delete("sms_%s" % mobile)
            customeruser_data = {}
            customeruser_data['username'] = realname
            customeruser_data['mobile'] = mobile
            customeruser_data['idcode'] = idcode
            customeruser_data['level_id'] = user.level_id
            customeruser_data['realname'] = realname
            customeruser_data['is_offline'] = 1
            customeruser_data['is_distributor'] = 1
            customeruser_data['create_time'] = datetime.datetime.now()
            customeruser_data['user'] = user.id
            customeruser_data['is_auth'] = 2
            customeruser, create = CustomerUser.objects.get_or_create(defaults=customeruser_data, mobile=mobile)
            relation_data = {}
            relation_data['manager_id'] = user.id
            relation_data['customer_id'] = customeruser.id
            ManagerCustomerRelation.objects.get_or_create(defaults=relation_data, customer_id=customeruser.id, manager_id=user.id)
        elif customeruser_id:
            try:
                customeruser = CustomerUser.objects.get(id=customeruser_id)
            except:
                return Response({'error': '无效用户id'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        level_id = user.level_id
        date_now = datetime.datetime.now()
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                instance_id = instance.id
                activity_id = activity.id
                while True:
                    instance = ActivityLevel.objects.get(id=instance_id)
                    activity = Activity.objects.get(id=activity_id)
                    origin_take_point = instance.take_point
                    origin_remain_point = instance.remain_point
                    origin_p_take_point = instance.p_take_point
                    origin_p_remain_point = instance.p_remain_point
                    if origin_remain_point < total_point:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
                    new_take_point = origin_take_point + total_point
                    new_remain_point = origin_remain_point - total_point
                    new_p_take_point = origin_p_take_point + total_point
                    new_p_remain_point = origin_p_remain_point - total_point
                    result = ActivityLevel.objects.filter(id=instance_id, take_point=origin_take_point, remain_point=origin_remain_point,
                                                          p_take_point=origin_p_take_point, p_remain_point=origin_remain_point).update(
                        take_point=new_take_point, remain_point=new_remain_point, p_take_point=new_p_take_point, p_remain_point=new_p_remain_point
                    )
                    activity_origin_take_point = activity.take_point
                    activity_origin_remain_point = activity.remain_point
                    activity_new_take_point = activity_origin_take_point + total_point
                    activity_new_remain_point = activity_origin_remain_point - total_point
                    result1 = Activity.objects.filter(id=activity_id, take_point=activity_origin_take_point, remain_point=activity_origin_remain_point).update(
                        take_point=activity_new_take_point, remain_point=activity_new_remain_point
                    )
                    if result == 0 or result1 == 0:
                        continue
                    relation_set = instance.child_set.all()
                    for relation in relation_set:
                        parent = relation.parent
                        parent.p_take_point += 1
                        parent.p_remain_point -= 1
                        parent.save()
                    break
                order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%06d' % randint(0, 999999)) + ('%09d' % customeruser.id)
                order_data = {}
                order_data['order_id'] = order_id
                order_data['customer_user_id'] = customeruser.id
                order_data['create_time'] = date_now
                order_data['total_count'] = total_count
                order_data['total_price'] = total_price
                order_data['total_point'] = total_point
                order_data['state'] = 3
                order_data['merchant_id'] = merchant_id
                order_data['payable_amount'] = 0
                order_data['reserved_mobile'] = customeruser.mobile
                order_data['order_type'] = order_type
                order_data['level_id'] = level_id
                order_data['use_time'] = date_now
                order = OrderInfo.objects.create(**order_data)
                for goods_data in goods_array:
                    while True:
                        goods_id = goods_data['goods_id']
                        count = int(goods_data['count'])
                        goods = Goods.objects.get(id=goods_id)
                        origin_stock = goods.stock
                        origin_sales = goods.sales
                        origin_remain_stock = goods.remain_stock
                        launchedgoods = LaunchedGoods.objects.filter(goods_id=goods_id, level_id=level_id).first()
                        if not launchedgoods:
                            return Response({'error': '库存不足'}, status=status.HTTP_400_BAD_REQUEST)
                        launched_origin_stock = launchedgoods.stock
                        launched_origin_sales = launchedgoods.sales
                        if count > launched_origin_stock:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '库存不足'}, status=status.HTTP_400_BAD_REQUEST)
                        launchedgoods_id = launchedgoods.id
                        launched_new_stock = launched_origin_stock - count
                        launched_new_sales = launched_origin_sales + count
                        new_sales = origin_sales + count
                        new_remain_stock = origin_remain_stock - count
                        launched_result = LaunchedGoods.objects.filter(id=launchedgoods_id, stock=launched_origin_stock).update(stock=launched_new_stock, sales=launched_new_sales)
                        result = Goods.objects.filter(id=goods_id).update(sales=new_sales, remain_stock=new_remain_stock)
                        if launched_result == 0:
                            continue
                        ordergoods = OrderGoods.objects.create(
                            order=order,
                            goods=goods,
                            count=count,
                            price=goods.price,
                            merchant_id=goods.merchant_id,
                            launched_goods_id=launchedgoods_id
                        )
                        for i in range(ordergoods.count):
                            while True:
                                coupons_id = '%16d' % randint(0, 9999999999999999)
                                goodscoupons = GoodsCoupons.objects.filter(coupons_id=coupons_id)
                                if not goodscoupons:
                                    break
                            GoodsCoupons.objects.create(
                                coupons_id=coupons_id,
                                status=2,
                                goods_id=ordergoods.goods_id,
                                order_id=order.id,
                                validity_time=date_now,
                                use_time=date_now,
                                use_user_id=user.id
                            )
                        break
                activity_data = {}
                activity_data['activity_data_id'] = timezone.now().strftime('%Y%m%d%H%M%S') + ('%06d' % randint(0, 999999)) + ('%09d' % customeruser.id)
                activity_data['point'] = total_point
                activity_data['create_time'] = date_now
                activity_data['received_time'] = date_now
                activity_data['use_time'] = date_now
                activity_data['activity_id'] = activity.id
                activity_data['customer_user_id'] = customeruser.id
                activity_data['level_id'] = level_id
                activity_data['state'] = 6
                activity_data['companyuser_id'] = user.id
                activity_data['phone'] = user.mobile
                activity_data['activity_level_id'] = instance.id
                activity_dat = ActivityData.objects.create(**activity_data)
                in_pointrecord_data = {}
                in_pointrecord_data['customer_user_id'] = customeruser.id
                in_pointrecord_data['create_time'] = date_now
                in_pointrecord_data['operate_type'] = 1
                in_pointrecord_data['business_type'] = 1
                in_pointrecord_data['point'] = total_point
                in_pointrecord_data['point_balance'] = total_point + customeruser.point
                in_pointrecord_data['remain_point'] = total_point
                in_pointrecord_data['activity_data_id'] = activity_dat.id
                PointRecord.objects.create(**in_pointrecord_data)
                out_pointrecord_data = {}
                out_pointrecord_data['customer_user_id'] = customeruser.id
                out_pointrecord_data['create_time'] = date_now
                out_pointrecord_data['operate_type'] = 2
                out_pointrecord_data['business_type'] = 2
                out_pointrecord_data['point'] = total_point
                out_pointrecord_data['point_balance'] = customeruser.point
                out_pointrecord_data['remain_point'] = 0
                out_pointrecord_data['order_id'] = order.id
                out_pointrecord_data['activity_data_id'] = activity_dat.id
                PointRecord.objects.create(**out_pointrecord_data)
                activity_level_record_data = {}
                activity_level_record_data['point'] = total_point
                activity_level_record_data['operation_type'] = 5
                activity_level_record_data['activity_level_id'] = instance.id
                activity_level_record_data['remain_point'] = new_remain_point
                activity_level_record_data['user_id'] = user.id
                activity_level_record_data['create_time'] = date_now
                activity_level_record_data['level_id'] = user.level_id
                activity_level_record_data['remark'] = '派发邮米'
                activity_level_record_data['activity_data_id'] = activity_dat.id
                ActivityLevelRecord.objects.create(**activity_level_record_data)
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '活动剩余邮米发生变化,请刷新重试'}, status=status.HTTP_400_BAD_REQUEST)
        transaction.savepoint_commit(save_id)
        return Response({'success': '派发成功'}, status=status.HTTP_200_OK)

    def sms_codes(self, request):
        mobile = self.request.query_params.get('mobile', None)
        if not mobile:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn = get_redis_connection("verify_code")
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, 1800, sms_code)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        pl.execute()
        content = f'【微邮付】登录验证码为：{sms_code}，若非本人操作，请忽略。'
        result = common_msg(mobile, content)
        return Response({"errmsg": "发送短信验证码成功"}, status=status.HTTP_200_OK)


class ActivityDataModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('phone', )
    filter_class = ActivityDataFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        queryset = ActivityData.objects.filter(level_id=level.id).order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return ActivityDataListModelSerializer
        else:
            return ActivityDataRetrieveModelSerializer

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.state not in [1, 2]:
            return Response({'error': '当前邮米派发记录不可撤销'}, status=status.HTTP_400_BAD_REQUEST)
        activity_level = instance.activity_level
        activity = instance.activity
        point = instance.point
        activity_level.take_point -= point
        activity_level.remain_point += point
        activity_level.p_take_point -= point
        activity_level.p_remain_point += point
        activity_level.save()
        activity.take_point -= point
        activity.remain_point += point
        activity.save()
        relation_set = activity_level.child_set.all()
        for relation in relation_set:
            parent = relation.parent
            parent.p_take_point -= 1
            parent.p_remain_point += 1
            parent.save()
        date_now = datetime.datetime.now()
        if instance.state == 2:
            customer_user = instance.customer_user
            out_pointrecord_data = {}
            out_pointrecord_data['customer_user_id'] = customer_user.id
            out_pointrecord_data['create_time'] = date_now
            out_pointrecord_data['operate_type'] = 2
            out_pointrecord_data['business_type'] = 3
            out_pointrecord_data['point'] = point
            out_pointrecord_data['point_balance'] = customer_user.point - point
            out_pointrecord_data['remain_point'] = 0
            out_pointrecord_data['activity_data_id'] = instance.id
            PointRecord.objects.create(**out_pointrecord_data)
            customer_user.point -= point
            customer_user.save()
        instance.state = 5
        instance.remain_point = 0
        instance.expired_time = date_now
        instance.save()
        return Response({'success': '撤销成功'}, status=status.HTTP_200_OK)


class LevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'account')
    serializer_class = LevelListSerializer

    # def get_serializer_class(self):
    #     if self.action == 'list':
    #         return LevelListSerializer
    #     else:
    #         return LevelRetrieveSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        goods_id = self.request.query_params.get('goods_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        if goods_id:
            goods = Goods.objects.filter(id=goods_id).first()
            if goods:
                queryset = queryset.filter(merchantenter__merchant_id=goods.merchant_id).exclude(launchedgoods__goods_id=goods_id).filter(level=4)
        return queryset


class CashActivityLevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('cash_activity__name', )
    filter_class = CashActivityLevelFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        date_now = datetime.datetime.now()
        queryset = CashActivityLevel.objects.filter(level_id=level.id, cash_activity__activity_state__in=[2], cash_activity__available_begin_time__lte=date_now).order_by('-id')
        return queryset

    def get_serializer_context(self):
        user = self.request.iser
        if self.action == 'retrieve':
            instance = self.get_object()
            return {'cash_activity': instance.cash_activity, 'user': user}

    def get_serializer_class(self):
        if self.action == 'list':
            return CashActivityLevelListModelSerializer
        else:
            return CashActivityLevelRetrieveModelSerializer

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        activity = instance.cash_activity
        rule_id = self.request.data.get('rule_id', None)
        if activity.activity_state != 2:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.is_auth != 1:
            return Response({'error': '当前机构未授权派发权限'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.activity_type in [1, 4]:
            amount = self.request.data.get('amount', None)
            if not amount:
                return Response({'error': '请输入派发金额'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                amount = Decimal(amount)
            except:
                return Response({'error': '请输入数值'}, status=status.HTTP_400_BAD_REQUEST)
            if amount > activity.max_distributed_amount:
                return Response({'error': '派发金额超过活动限制'}, status=status.HTTP_400_BAD_REQUEST)
            if amount < activity.min_distributed_amount:
                return Response({'error': '派发金额低于活动派发最小金额'}, status=status.HTTP_400_BAD_REQUEST)
        elif activity.activity_type in [2, 5]:
            if not rule_id:
                return Response({'error': '请上传派发规则id'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                cash_activity_rule = CashActivityRule.objects.get(id=rule_id, cash_activity_id=activity.id)
            except:
                return Response({'error': '无效派发规则id'}, status=status.HTTP_400_BAD_REQUEST)
            if cash_activity_rule.probability < 1:
                return Response({'error': '无效派发规则id'}, status=status.HTTP_400_BAD_REQUEST)
            amount = cash_activity_rule.amount
        else:
            cashactivityrule_set = CashActivityRule.objects.filter(cash_activity_id=activity.id, is_delete=0)
            list_data = []
            if activity.activity_type == 3:
                for cashactivityrule in cashactivityrule_set:
                    if cashactivityrule.amount <= instance.remain_amount:
                        probability = int(cashactivityrule.probability.quantize(Decimal("0")))
                        for i in range(probability):
                            list_data.append(cashactivityrule.amount)
            elif activity.activity_type == 6:
                for cashactivityrule in cashactivityrule_set:
                    if cashactivityrule.amount <= activity.remain_amount:
                        probability = int(cashactivityrule.probability.quantize(Decimal("0")))
                        for i in range(probability):
                            list_data.append(cashactivityrule.amount)
            if not list_data:
                return Response({'error': '活动未配置随机规则'}, status=status.HTTP_400_BAD_REQUEST)
            amount = random.choices(list_data, k=1)[0]
        if activity.is_max_amount_by_day == 1:
            today_time_begin = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
            today_time_end = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
            max_amount_by_day__sum = CashActivityData.objects.filter(cash_activity_id=activity.id, create_time__gte=today_time_begin, create_time__lte=today_time_end, state__in=[1, 2]).aggregate(Sum('amount'))['amount__sum']
            if max_amount_by_day__sum:
                max_amount_by_day__sum = Decimal(max_amount_by_day__sum) + amount
                if max_amount_by_day__sum > activity.max_amount_by_day:
                    return Response({'error': '活动派发额度已达到今日上限,请明日派发', 'status': ''}, status=status.HTTP_400_BAD_REQUEST)
        if activity.is_max_amount_by_user_by_day == 1:
            today_time_begin = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
            today_time_end = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
            max_amount_by_user_by_day__sum = CashActivityData.objects.filter(cash_activity_id=activity.id, create_time__gte=today_time_begin, create_time__lte=today_time_end, companyuser_id=user.id, state__in=[1, 2]).aggregate(Sum('amount'))['amount__sum']
            if max_amount_by_user_by_day__sum:
                max_amount_by_user_by_day__sum = Decimal(max_amount_by_user_by_day__sum) + amount
                if max_amount_by_user_by_day__sum > activity.max_amount_by_user_by_day:
                    return Response({'error': '客户经理派发额度已达到今日上限,请明日派发', 'status': ''}, status=status.HTTP_400_BAD_REQUEST)
        if activity.is_max_amount_by_user == 1:
            max_amount_by_user__sum = CashActivityData.objects.filter(cash_activity_id=activity.id, companyuser_id=user.id, state__in=[1, 2]).aggregate(Sum('amount'))['amount__sum']
            if max_amount_by_user__sum:
                max_amount_by_user__sum = Decimal(max_amount_by_user__sum) + amount
                if max_amount_by_user__sum > activity.max_amount_by_user:
                    return Response({'error': '客户经理派发额度已达上限', 'status': ''}, status=status.HTTP_400_BAD_REQUEST)
        if activity.activity_type in [1, 2, 3]:
            if instance.remain_amount < amount:
                return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            if activity.remain_amount < amount:
                return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        date_now = datetime.datetime.now()
        today_time_begin = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
        today_time_end = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
        pay_type = 1
        if amount > Decimal('100'):
            pay_type = 2
        encouragedraw = CashActivityData.objects.filter(received_time__gte=today_time_begin, received_time__lte=today_time_end, return_msg__contains='已达到今日商户付款额度上限')
        if encouragedraw:
            pay_type = 2
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                instance_id = instance.id
                activity_id = activity.id
                if activity.activity_type in [1, 2, 3]:
                    while True:
                        instance = CashActivityLevel.objects.get(id=instance_id)
                        origin_take_amount = instance.take_amount
                        origin_remain_amount = instance.remain_amount
                        origin_p_take_amount = instance.p_take_amount
                        origin_p_remain_amount = instance.p_remain_amount
                        if origin_remain_amount < amount:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
                        new_take_amount = origin_take_amount + amount
                        new_remain_amount = origin_remain_amount - amount
                        new_p_take_amount = origin_p_take_amount + amount
                        new_p_remain_amount = origin_p_remain_amount - amount
                        result = CashActivityLevel.objects.filter(id=instance_id, take_amount=origin_take_amount, remain_amount=origin_remain_amount,
                                                              p_take_amount=origin_p_take_amount, p_remain_amount=origin_p_remain_amount).update(
                            take_amount=new_take_amount, remain_amount=new_remain_amount, p_take_amount=new_p_take_amount, p_remain_amount=new_p_remain_amount
                        )
                        if result == 0:
                            continue
                        relation_set = instance.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_take_amount += amount
                            parent.p_remain_amount -= amount
                            parent.save()
                        break
                    while True:
                        activity = CashActivity.objects.get(id=activity_id)
                        activity_origin_take_amount = activity.take_amount
                        activity_origin_remain_amount = activity.remain_amount
                        activity_new_take_amount = activity_origin_take_amount + amount
                        activity_new_remain_amount = activity_origin_remain_amount - amount
                        result = CashActivity.objects.filter(take_amount=activity_origin_take_amount, remain_amount=activity_origin_remain_amount, id=activity_id).update(
                            take_amount=activity_new_take_amount, remain_amount=activity_new_remain_amount)
                        if result == 0:
                            continue
                        break
                else:
                    while True:
                        activity = CashActivity.objects.get(id=activity_id)
                        activity_origin_take_amount = activity.take_amount
                        activity_origin_remain_amount = activity.remain_amount
                        if activity_origin_remain_amount < amount:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
                        activity_new_take_amount = activity_origin_take_amount + amount
                        activity_new_remain_amount = activity_origin_remain_amount - amount
                        result = CashActivity.objects.filter(take_amount=activity_origin_take_amount, remain_amount=activity_origin_remain_amount, id=activity_id).update(
                            take_amount=activity_new_take_amount, remain_amount=activity_new_remain_amount)
                        if result == 0:
                            continue
                        break
                    while True:
                        instance = CashActivityLevel.objects.get(id=instance_id)
                        origin_take_amount = instance.take_amount
                        origin_max_amount = instance.max_amount
                        origin_p_take_amount = instance.p_take_amount
                        origin_p_max_amount = instance.p_max_amount
                        new_take_amount = origin_take_amount + amount
                        new_max_amount = origin_max_amount + amount
                        new_p_take_amount = origin_p_take_amount + amount
                        new_p_max_amount = origin_p_max_amount + amount
                        result = CashActivityLevel.objects.filter(id=instance_id, take_amount=origin_take_amount, max_amount=origin_max_amount,
                                                              p_take_amount=origin_p_take_amount, p_max_amount=origin_p_max_amount).update(
                            take_amount=new_take_amount, p_take_amount=new_p_take_amount,
                            max_amount=new_max_amount, p_max_amount=new_p_max_amount
                        )
                        if result == 0:
                            continue
                        relation_set = instance.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_take_amount += amount
                            parent.p_max_amount += amount
                            parent.save()
                        break
                activity_data = {}
                activity_data['amount'] = amount
                activity_data['create_time'] = date_now
                activity_data['cash_activity_id'] = activity.id
                activity_data['level_id'] = user.level_id
                activity_data['state'] = 1
                activity_data['companyuser_id'] = user.id
                activity_data['cash_activity_level_id'] = instance.id
                identify = random_str()
                nonce_str = random_str()
                common_url = f'https://api.sutpay.com/customer/cash/?identify={identify}'
                common_qrcode = f'youhuiquanyi/activity/{identify}.png'
                common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                activity_data['identify'] = identify
                activity_data['common_qrcode'] = common_qrcode
                activity_data['common_url'] = common_url
                activity_data['nonce_str'] = nonce_str
                activity_data['desc'] = activity.name
                activity_data['partner_trade_no'] = f'{date_now.strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}{"%06d" % user.id}'
                activity_data['expired_time'] = date_now + datetime.timedelta(hours=11)
                activity_dat, create = CashActivityData.objects.get_or_create(defaults=activity_data, identify=identify)
                if not create:
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '活动剩余邮米发生变化,请刷新重试'}, status=status.HTTP_400_BAD_REQUEST)
                if activity.activity_type in [2, 5]:
                    cash_activity_rule = CashActivityRule.objects.get(id=rule_id, cash_activity_id=activity.id)
                    cash_activity_rule.probability -= 1
                    cash_activity_rule.save()
                    activity_dat.cash_activity_rule_id = cash_activity_rule.id
                    activity_dat.save()
                if activity.activity_type in [1, 2, 3]:
                    try:
                        cashactivitylevelrecord_data = {}
                        cashactivitylevelrecord_data['activity_level_id'] = instance.id
                        cashactivitylevelrecord_data['amount'] = amount
                        cashactivitylevelrecord_data['operation_type'] = 5
                        cashactivitylevelrecord_data['remain_amount'] = new_remain_amount
                        cashactivitylevelrecord_data['p_remain_amount'] = new_p_remain_amount
                        cashactivitylevelrecord_data['max_amount'] = instance.max_amount
                        cashactivitylevelrecord_data['p_max_amount'] = instance.p_max_amount
                        cashactivitylevelrecord_data['user_id'] = user.id
                        cashactivitylevelrecord_data['remark'] = '客户经理通过小程序生成派发二维码'
                        cashactivitylevelrecord_data['activity_data_id'] = activity_dat.id
                        cashactivitylevelrecord_data['activity_id'] = activity.id
                        CashActivityLevelRecord.objects.create(**cashactivitylevelrecord_data)
                    except Exception as e:
                        print(e)
                        pass
                else:
                    try:
                        cashactivitylevelrecord_data = {}
                        cashactivitylevelrecord_data['activity_level_id'] = instance.id
                        cashactivitylevelrecord_data['amount'] = amount
                        cashactivitylevelrecord_data['operation_type'] = 5
                        cashactivitylevelrecord_data['activity_type'] = 2
                        cashactivitylevelrecord_data['remain_amount'] = activity_new_remain_amount
                        cashactivitylevelrecord_data['p_remain_amount'] = activity_new_remain_amount
                        cashactivitylevelrecord_data['max_amount'] = activity.max_amount
                        cashactivitylevelrecord_data['p_max_amount'] = activity.max_amount
                        cashactivitylevelrecord_data['user_id'] = user.id
                        cashactivitylevelrecord_data['remark'] = '客户经理通过小程序生成派发二维码'
                        cashactivitylevelrecord_data['activity_data_id'] = activity_dat.id
                        cashactivitylevelrecord_data['activity_id'] = activity.id
                        CashActivityLevelRecord.objects.create(**cashactivitylevelrecord_data)
                    except Exception as e:
                        print(e)
                        pass
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '活动剩余邮米发生变化,请刷新重试'}, status=status.HTTP_400_BAD_REQUEST)
        transaction.savepoint_commit(save_id)
        data = CashActivityLevelRetrieveModelSerializer(instance, context={'cash_activity': activity}).data
        data['common_qrcode'] = activity_dat.common_qrcode.url
        data['expired_time'] = activity_dat.expired_time.strftime("%Y.%m.%d %H:%M:%S")
        data['amount'] = amount
        data['pay_type'] = pay_type
        if user.id == 1:
            eta = datetime.datetime.utcnow() + datetime.timedelta(seconds=50)
        else:
            eta = datetime.datetime.utcnow() + datetime.timedelta(hours=11)
        task_id = detection_cash_activity_qrcode.apply_async(({"activityqrcode_id": activity_dat.id},), eta=eta)
        try:
            activity_dat.task_id = task_id
            activity_dat.save()
        except:
            pass
        return Response(data, status=status.HTTP_200_OK)

    def cash_distributed_statistical(self, request):
        cash_activity_level_id = self.request.query_params.get('cash_activity_level_id', None)
        dimensionality = self.request.query_params.get('dimensionality', '3')
        sort = self.request.query_params.get('sort', '0')
        user = self.request.iser
        level_level_id = user.level.level
        if not cash_activity_level_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=cash_activity_level_id)
        except:
            return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
        if level_level_id not in [0, 1, 2] and dimensionality == '1':
            return Response({'error': '当前客户经理等级不能查看市级数据统计'}, status=status.HTTP_400_BAD_REQUEST)
        if level_level_id not in [0, 1, 2, 3] and dimensionality == '2':
            return Response({'error': '当前客户经理等级不能查看区县级数据统计'}, status=status.HTTP_400_BAD_REQUEST)
        if dimensionality == '1':
            queryset = CashActivityLevel.objects.filter(level__level=2, child_set__parent_id=instance.id)
        elif dimensionality == '2':
            queryset = CashActivityLevel.objects.filter(level__level=3, child_set__parent_id=instance.id)
        else:
            queryset = CashActivityLevel.objects.filter(level__level=4, child_set__parent_id=instance.id)
        if sort == '0':
            queryset = queryset.order_by('p_max_amount', 'id')
        elif sort == '1':
            queryset = queryset.order_by('-p_max_amount', 'id')
        elif sort == '2':
            queryset = queryset.order_by('p_take_amount', 'id')
        elif sort == '3':
            queryset = queryset.order_by('-p_take_amount', 'id')
        elif sort == '4':
            queryset = queryset.order_by('p_receive_amount', 'id')
        elif sort == '5':
            queryset = queryset.order_by('-p_receive_amount', 'id')
        elif sort == '6':
            queryset = queryset.order_by(F('p_take_amount') - F('p_receive_amount'), 'id')
        elif sort == '7':
            queryset = queryset.order_by(-(F('p_take_amount') - F('p_receive_amount')), 'id')
        elif sort == '8':
            queryset = queryset.order_by(F('p_take_amount') / F('p_max_amount'), 'id')
        elif sort == '9':
            queryset = queryset.order_by(-F('p_take_amount') / F('p_max_amount'), 'id')
        elif sort == '10':
            queryset = queryset.order_by(F('p_remain_amount') / F('p_max_amount'), 'id')
        elif sort == '11':
            queryset = queryset.order_by(-F('p_remain_amount') / F('p_max_amount'), 'id')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CashActivityLevelStatisticalModelSerializer(page, many=True, context={'cash_activity': instance.cash_activity})
            return self.get_paginated_response(serializer.data)
        serializer = CashActivityLevelStatisticalModelSerializer(queryset, many=True, context={'cash_activity': instance.cash_activity})
        return Response(serializer.data)

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        activity = instance.cash_activity
        if activity.is_limit_white != 1:
            return Response({'error': '活动不支持客户经理添加白名单'}, status=status.HTTP_400_BAD_REQUEST)
        mobile = self.request.data.get('mobile', None)
        business_no = self.request.data.get('business_no', None)
        if not mobile:
            return Response({'error': '请上传白名单用户手机号'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({'error': '手机号格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        check_white = CashActivityWhiteTable.objects.filter(cashactivity_id=activity.id, mobile=mobile)
        if check_white:
            return Response({'error': '手机号白名单重复'}, status=status.HTTP_400_BAD_REQUEST)
        white_accout = CashActivityWhiteTable.objects.filter(cashactivity_id=activity.id, add_user_id=user.id).count()
        if white_accout >= activity.white_accout:
            return Response({'error': '白名单额度已超过限制'}, status=status.HTTP_400_BAD_REQUEST)
        defaults = {}
        defaults['cashactivity_id'] = activity.id
        defaults['level_id'] = user.level_id
        defaults['add_user_id'] = user.id
        defaults['mobile'] = mobile
        if activity.is_white_merchant == 1:
            if not business_no:
                return Response({'error': '请上传微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
            business_no = str(business_no)
            if not business_no.isdigit() and len(business_no) != 10:
                return Response({'error': '请输入10位纯数字微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
            check_merchant = Merchant.objects.filter(wyfMerchantID=business_no)
            if not check_merchant:
                result = searchmerchantmsg(business_no)
                if result['result_code'] != 'success':
                    return Response({'error': '无效微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
            check_white_count = CashActivityWhiteTable.objects.filter(cashactivity_id=activity.id, business_no=business_no).count()
            if check_white_count >= activity.repeat_business_no_count:
                return Response({'error': '商户白名单重复数量超过限制'}, status=status.HTTP_400_BAD_REQUEST)
            defaults['business_no'] = business_no
            CashActivityWhiteTable.objects.get_or_create(cashactivity_id=activity.id, business_no=business_no, defaults=defaults, mobile=mobile)
        else:
            CashActivityWhiteTable.objects.get_or_create(cashactivity_id=activity.id, defaults=defaults, mobile=mobile)
        return Response({'success': '添加成功'}, status=status.HTTP_200_OK)


class CashActivityWhiteTableModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('mobile', 'business_no')
    # filter_class = CashActivityWhiteTableFilter
    serializer_class = CashActivityWhiteTableModelSerializer

    def get_queryset(self):
        user = self.request.iser
        cash_activity_level_id = self.request.query_params.get('cash_activity_level_id', None)
        is_admin = self.request.query_params.get('is_admin', None)
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['total_white_accout'] = '0'
        self.request.data['white_accout'] = '0'
        if cash_activity_level_id:
            try:
                instance = CashActivityLevel.objects.get(id=cash_activity_level_id)
                queryset = CashActivityWhiteTable.objects.filter(cashactivity_id=instance.cash_activity_id)
                cash_activity = instance.cash_activity
                self.request.data['total_white_accout'] = str(cash_activity.white_accout)
                if cash_activity.is_limit_white == 1:
                    white_accout = CashActivityWhiteTable.objects.filter(cashactivity_id=cash_activity.id, add_user_id=user.id).count()
                    self.request.data['white_accout'] = str(white_accout)
            except:
                queryset = CashActivityWhiteTable.objects.filter(id=1)
        else:
            queryset = CashActivityWhiteTable.objects.filter(id=1)
        if is_admin == '0':
            queryset = queryset.filter(add_user_id=user.id)
        # elif is_admin == '1':
        #     queryset = queryset.exclude(add_user_id=user.id)
        return queryset.order_by('-id')


class CashActivityDataModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = CashActivityDataFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        cash_activity_level_id = self.request.query_params.get('cash_activity_level_id', None)
        if level.level == 0:
            queryset = CashActivityData.objects.all().order_by('-id')
        elif level.level == 1:
            queryset = CashActivityData.objects.filter(level__prov_id=level.id).order_by('-id')
        elif level.level == 2:
            queryset = CashActivityData.objects.filter(level__city_id=level.id).order_by('-id')
        elif level.level == 3:
            queryset = CashActivityData.objects.filter(level__district_id=level.id).order_by('-id')
        else:
            queryset = CashActivityData.objects.filter(level__branch_id=level.id).order_by('-id')
        if cash_activity_level_id:
            try:
                activity_level = CashActivityLevel.objects.get(id=cash_activity_level_id)
                relation_set = list(activity_level.parent_set.all().values_list('child_id', flat=True))
                relation_set.append(cash_activity_level_id)
                queryset = queryset.filter(cash_activity_level_id__in=relation_set)
            except:
                queryset = queryset.filter(cash_activity_level_id=cash_activity_level_id)
        # queryset = CashActivityData.objects.filter(level_id=level.id).order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return CashActivityDataListModelSerializer
        else:
            return CashActivityDataRetrieveModelSerializer

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        user = self.request.iser
        if instance.state != 1:
            return Response({'error': '当前派发记录不可撤销'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.companyuser_id != user.id:
            return Response({'error': '您无权限撤销该派发'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.cash_activity
        cash_activity_id = instance.cash_activity_id
        cash_activity_level_id = instance.cash_activity_level_id
        amount = instance.amount
        if activity.activity_type in [1, 2, 3]:
            while True:
                activity_level = CashActivityLevel.objects.get(id=cash_activity_level_id)
                origin_take_amount = activity_level.take_amount
                origin_remain_amount = activity_level.remain_amount
                origin_p_take_amount = activity_level.p_take_amount
                origin_p_remain_amount = activity_level.p_remain_amount
                new_take_amount = origin_take_amount - amount
                new_remain_amount = origin_remain_amount + amount
                new_p_take_amount = origin_p_take_amount - amount
                new_p_remain_amount = origin_p_remain_amount + amount
                result = CashActivityLevel.objects.filter(id=cash_activity_level_id, take_amount=origin_take_amount,
                                                          remain_amount=origin_remain_amount,
                                                          p_take_amount=origin_p_take_amount,
                                                          p_remain_amount=origin_p_remain_amount).update(
                    take_amount=new_take_amount, remain_amount=new_remain_amount, p_take_amount=new_p_take_amount,
                    p_remain_amount=new_p_remain_amount
                )
                if result == 0:
                    continue
                break
            while True:
                activity = CashActivity.objects.get(id=cash_activity_id)
                activity_origin_take_amount = activity.take_amount
                activity_origin_remain_amount = activity.remain_amount
                activity_new_take_amount = activity_origin_take_amount - amount
                activity_new_remain_amount = activity_origin_remain_amount + amount
                result = CashActivity.objects.filter(take_amount=activity_origin_take_amount,
                                                     remain_amount=activity_origin_remain_amount,
                                                     id=cash_activity_id).update(
                    take_amount=activity_new_take_amount, remain_amount=activity_new_remain_amount)
                if result == 0:
                    continue
                break
            relation_set = activity_level.child_set.all()
            for relation in relation_set:
                parent = relation.parent
                parent.p_take_amount -= amount
                parent.p_remain_amount += amount
                parent.save()
            date_now = datetime.datetime.now()
            instance.state = 4
            instance.expired_time = date_now
            instance.save()
            try:
                cashactivitylevelrecord_data = {}
                cashactivitylevelrecord_data['activity_level_id'] = activity_level.id
                cashactivitylevelrecord_data['amount'] = amount
                cashactivitylevelrecord_data['operation_type'] = 6
                cashactivitylevelrecord_data['remain_amount'] = activity_level.remain_amount
                cashactivitylevelrecord_data['p_remain_amount'] = activity_level.p_remain_amount
                cashactivitylevelrecord_data['max_amount'] = activity_level.max_amount
                cashactivitylevelrecord_data['p_max_amount'] = activity_level.p_max_amount
                cashactivitylevelrecord_data['user_id'] = user.id
                cashactivitylevelrecord_data['remark'] = '客户经理撤销派发二维码'
                cashactivitylevelrecord_data['activity_data_id'] = instance.id
                cashactivitylevelrecord_data['activity_id'] = activity.id
                CashActivityLevelRecord.objects.create(**cashactivitylevelrecord_data)
                if instance.task_id:
                    celery_app.control.revoke(instance.task_id)
            except Exception as e:
                print(e)
                pass
        else:
            while True:
                activity_level = CashActivityLevel.objects.get(id=cash_activity_level_id)
                origin_take_amount = activity_level.take_amount
                origin_max_amount = activity_level.max_amount
                origin_p_take_amount = activity_level.p_take_amount
                origin_p_max_amount = activity_level.p_max_amount
                new_take_amount = origin_take_amount - amount
                new_max_amount = origin_max_amount - amount
                new_p_take_amount = origin_p_take_amount - amount
                new_p_max_amount = origin_p_max_amount - amount
                result = CashActivityLevel.objects.filter(id=cash_activity_level_id, take_amount=origin_take_amount,
                                                          max_amount=origin_max_amount,
                                                          p_take_amount=origin_p_take_amount,
                                                          p_max_amount=origin_p_max_amount).update(
                    take_amount=new_take_amount, max_amount=new_max_amount, p_take_amount=new_p_take_amount,
                    p_max_amount=new_p_max_amount
                )
                if result == 0:
                    continue
                break
            while True:
                activity = CashActivity.objects.get(id=cash_activity_id)
                activity_origin_take_amount = activity.take_amount
                activity_origin_remain_amount = activity.remain_amount
                activity_new_take_amount = activity_origin_take_amount - amount
                activity_new_remain_amount = activity_origin_remain_amount + amount
                result = CashActivity.objects.filter(take_amount=activity_origin_take_amount,
                                                     remain_amount=activity_origin_remain_amount,
                                                     id=cash_activity_id).update(
                    take_amount=activity_new_take_amount, remain_amount=activity_new_remain_amount)
                if result == 0:
                    continue
                break
            relation_set = activity_level.child_set.all()
            for relation in relation_set:
                parent = relation.parent
                parent.p_take_amount -= amount
                parent.p_max_amount -= amount
                parent.save()
            date_now = datetime.datetime.now()
            instance.state = 4
            instance.expired_time = date_now
            instance.save()
            try:
                cashactivitylevelrecord_data = {}
                cashactivitylevelrecord_data['activity_level_id'] = activity_level.id
                cashactivitylevelrecord_data['amount'] = amount
                cashactivitylevelrecord_data['operation_type'] = 6
                cashactivitylevelrecord_data['activity_type'] = 2
                cashactivitylevelrecord_data['remain_amount'] = activity.remain_amount
                cashactivitylevelrecord_data['p_remain_amount'] = activity.remain_amount
                cashactivitylevelrecord_data['max_amount'] = activity.max_amount
                cashactivitylevelrecord_data['p_max_amount'] = activity_level.p_max_amount
                cashactivitylevelrecord_data['user_id'] = user.id
                cashactivitylevelrecord_data['remark'] = '客户经理撤销派发二维码'
                cashactivitylevelrecord_data['activity_data_id'] = instance.id
                cashactivitylevelrecord_data['activity_id'] = activity.id
                CashActivityLevelRecord.objects.create(**cashactivitylevelrecord_data)
                if instance.task_id:
                    celery_app.control.revoke(instance.task_id)
            except Exception as e:
                print(e)
                pass
        try:
            if activity.activity_type in [2, 5]:
                cash_activity_rule = instance.cash_activity_rule
                cash_activity_rule.probability += 1
                cash_activity_rule.save()
        except:
            pass
        return Response({'success': '撤销成功'}, status=status.HTTP_200_OK)


class CustomizeActivityLevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('customizeactivity__activity_name', )
    filter_class = CustomizeActivityLevelFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        date_now = datetime.datetime.now()
        queryset = CustomizeActivityLevel.objects.filter(level_id=level.id, customizeactivity__activity_status__in=[1], customizeactivity__available_begin_time__lte=date_now).order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return CustomizeActivityLevelListModelSerializer
        else:
            return CustomizeActivityLevelRetrieveModelSerializer

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        customizeactivity = instance.customizeactivity
        if customizeactivity.activity_type != 11:
            return Response({'error': '活动类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.remain_number <= 0:
            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        if customizeactivity.activity_status != 1:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        # if customizeactivity.max_number_by_day:
        #     begin_time = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
        #     end_time = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
        #     max_no = AliDiscountCouponInfo.objects.filter(alidiscountcoupon_id=customizeactivity.id, gmt_create__gte=begin_time, gmt_create__lte=end_time).count()
        #     if max_no >= customizeactivity.max_number_by_day:
        #         return Response({'error': '今天的优惠券已派发完毕，请次日参与！'}, status=status.HTTP_400_BAD_REQUEST)
        today = datetime.datetime.now()
        discountcouponqrcodedata = {}
        identify = random_str()
        if customizeactivity.drawdown_platform_id == 4:
            common_url = f'https://qrcode.sutpay.com/customer/couponbag/?identify={identify}'
        else:
            common_url = f'https://qrcode.sutpay.com/business/couponbag/?identify={identify}'
        common_qrcode = f'youhuiquanyi/couponbag/{identify}.png'
        common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
        discountcouponqrcodedata['identify'] = identify
        discountcouponqrcodedata['common_qrcode'] = common_qrcode
        discountcouponqrcodedata['common_url'] = common_url
        discountcouponqrcodedata['companyuser_id'] = user.id
        discountcouponqrcodedata['customizeactivity_level_id'] = instance.id
        discountcouponqrcodedata['gmt_distributed'] = today
        out_biz_no = f'{today.strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
        discountcouponqrcodedata['out_biz_no'] = out_biz_no
        discountcouponqrcodedata, create = CustomizeActivityQRCode.objects.get_or_create(defaults=discountcouponqrcodedata, identify=identify)
        data = CustomizeActivityLevelRetrieveModelSerializer(instance).data
        data['common_qrcode'] = discountcouponqrcodedata.common_qrcode.url
        return Response(data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        customizeactivity_level = self.get_object()
        mobile = self.request.data.get('mobile', None)
        user = self.request.iser
        if not mobile:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        customizeactivity = customizeactivity_level.customizeactivity
        if customizeactivity.activity_type != 11:
            return Response({'error': '活动类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if customizeactivity_level.remain_number <= 0:
            return Response({'error': '活动已达到派发上限'}, status=status.HTTP_400_BAD_REQUEST)
        if customizeactivity.activity_status != 1:
            return Response({'error': '活动已结束'}, status=status.HTTP_400_BAD_REQUEST)
        if customizeactivity.lucky_count_by_user:
            max_no = CustomizeActivityFlipCARDS.objects.filter(customizeactivity_id=customizeactivity.id, mobile=mobile).count()
            if max_no >= customizeactivity.lucky_count_by_user:
                return Response({'error': '用户参与活动次数已达上限，感谢您对本活动的支持！'}, status=status.HTTP_400_BAD_REQUEST)
        if customizeactivity.drawdown_platform_id != 4:
            return Response({'error': '当前活动不支持登记派发！'}, status=status.HTTP_400_BAD_REQUEST)
        customeruser = CustomerUser.objects.filter(mobile=mobile).first()
        if not customeruser:
            customeruser, create = CustomerUser.objects.get_or_create(mobile=mobile, defaults={'mobile': mobile, 'create_time': datetime.datetime.now()})
        if customizeactivity_level.remain_number <= 0:
            return Response({'error': '活动额度已派完'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                customizeactivity_level_id = customizeactivity_level.id
                while True:
                    customizeactivity_level = CustomizeActivityLevel.objects.get(id=customizeactivity_level_id)
                    origin_take_number = customizeactivity_level.take_number
                    origin_remain_number = customizeactivity_level.remain_number
                    origin_receive_number = customizeactivity_level.receive_number
                    if origin_remain_number <= 0:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '活动额度已派完'}, status=status.HTTP_400_BAD_REQUEST)
                    new_take_number = origin_take_number + 1
                    new_remain_number = origin_remain_number - 1
                    new_receive_number = origin_receive_number + 1
                    result = CustomizeActivityLevel.objects.filter(id=customizeactivity_level_id, take_number=origin_take_number, receive_number=origin_receive_number,remain_number=origin_remain_number).update(take_number=new_take_number, receive_number=new_receive_number, remain_number=new_remain_number)
                    if result == 0:
                        continue
                    break
                today = datetime.datetime.now()
                identify = f'{today.strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                defaults = {}
                defaults['user_id'] = customeruser.id
                defaults['open_status'] = 2
                defaults['identify'] = identify
                defaults['pay_time'] = today
                defaults['gears'] = 1
                defaults['win_type'] = 8
                defaults['customizeactivity_id'] = customizeactivity_level.customizeactivity_id
                defaults['level_id'] = user.level_id
                defaults['mobile'] = mobile
                defaults['companyuser_id'] = user.id
                defaults['open_time'] = today
                instance, create = CustomizeActivityFlipCARDS.objects.get_or_create(defaults=defaults, identify=identify)
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '派发失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '派发成功'}, status=status.HTTP_200_OK)


class CustomizeActivityFlipCARDSModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    # search_fields = ('customizeactivity__activity_name', )
    filter_class = CustomizeActivityFlipCARDSFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        queryset = CustomizeActivityFlipCARDS.objects.filter(level_id=level.id, open_status__in=[2, 4, 6]).order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return CustomizeActivityFlipCARDSListModelSerializer
        else:
            return CustomizeActivityFlipCARDSRetrieveModelSerializer


class MerchantBusinessQRCodeModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__wyfMerchantID', 'sn', 'merchant__name')
    filter_class = MerchantBusinessQRCodeFilter

    def get_queryset(self):
        user = self.request.iser
        queryset = MerchantBusinessQRCode.objects.filter(user_id=user.id)
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantBusinessQRCodeListModelSerializer
        else:
            return MerchantBusinessQRCodeRetrieveModelSerializer

    def list(self, request, *args, **kwargs):
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['activity_time'] = f'2023.09.15~2023.12.31'
        return super().list(request, *args, **kwargs)

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        # if instance.is_achieve != 1:
        #     return Response({'error': '码牌未完成邀新任务'}, status=status.HTTP_400_BAD_REQUEST)
        cashactivitydata = instance.cashactivitydata
        if instance.award_status != 0:
            return Response({'error': '奖励状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if cashactivitydata.state != 1:
            return Response({'error': '奖励状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        cash_activity_id = cashactivitydata.cash_activity_id
        appid = cashactivitydata.appid
        openid = cashactivitydata.openid
        today_time_begin = datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')
        today_time_end = datetime.datetime.now().strftime('%Y-%m-%d 23:59:59')
        encouragedraw = CashActivityData.objects.filter(received_time__gte=today_time_begin, received_time__lte=today_time_end, return_msg__contains='已达到今日商户付款额度上限')
        if encouragedraw:
            return Response({'error': '微信额度已达到今日上限,请明日领取', 'status': ''}, status=status.HTTP_400_BAD_REQUEST)
        encouragedraw_set = CashActivityData.objects.filter(received_time__gte=today_time_begin,
                                                            received_time__lte=today_time_end,
                                                            openid=openid, state=2)
        if len(encouragedraw_set) >= 10:
            return Response({'error': '领取次数已达到今日上限,请明日领取', 'status': ''}, status=status.HTTP_400_BAD_REQUEST)
        today_amount = Decimal('0')
        for encouragedraw in encouragedraw_set:
            today_amount += encouragedraw.amount
        today_amount += cashactivitydata.amount
        if today_amount > Decimal('500'):
            return Response({'error': '微信额度已达到今日上限,请明日领取', 'status': ''}, status=status.HTTP_400_BAD_REQUEST)
        cashactivitydata.state = 5
        cashactivitydata.save()
        mchid = '1486198522'
        params = {
            'mch_appid': appid,
            'mchid': '1486198522',
            'nonce_str': cashactivitydata.nonce_str,
            'partner_trade_no': cashactivitydata.partner_trade_no,
            'openid': openid,
            'check_name': 'NO_CHECK',
            'amount': int(cashactivitydata.amount * 100),
            'desc': cashactivitydata.desc
        }
        data_dict = mmpaymkttransfers(params)
        if data_dict['result_code'] == 'SUCCESS':
            cashactivitydata.state = 2
            cashactivitydata.received_time = data_dict['payment_time']
            cashactivitydata.payment_no = data_dict['payment_no']
            cashactivitydata.mchid = mchid
            cashactivitydata.mobile = user.mobile
            cashactivitydata.save()
            instance.award_status = 1
            instance.save()
            while True:
                activity = CashActivity.objects.get(id=cash_activity_id)
                origin_distributed_amount = activity.distributed_amount
                new_distributed_amount = origin_distributed_amount + cashactivitydata.amount
                result = CashActivity.objects.filter(id=cash_activity_id, distributed_amount=origin_distributed_amount).update(
                    distributed_amount=new_distributed_amount)
                if result == 0:
                    continue
                break
            return Response({'success': '领取成功', 'status': ''}, status=status.HTTP_200_OK)
        else:
            cashactivitydata.return_msg = data_dict['err_code_des']
            cashactivitydata.state = 3
            cashactivitydata.received_time = datetime.datetime.now()
            cashactivitydata.mchid = mchid
            cashactivitydata.mobile = user.mobile
            cashactivitydata.save()
            return Response({'error': f'领取失败,{data_dict["err_code_des"]}'}, status=status.HTTP_400_BAD_REQUEST)


class MerchantBusinessQRCodeVisitModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    # search_fields = ('merchant__wyfMerchantID', 'sn')
    filter_class = MerchantBusinessQRCodeVisitFilter

    def get_queryset(self):
        user = self.request.iser
        queryset = MerchantBusinessQRCodeVisit.objects.filter(qrcode__user=user.id).order_by('-create_time')
        return queryset

    def get_serializer_class(self):
        return MerchantBusinessQRCodeVisitListModelSerializer


class CustomerUserViceInviterRecordModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    # search_fields = ('merchant__wyfMerchantID', 'sn')
    filter_class = CustomerUserViceInviterRecordFilter

    def get_queryset(self):
        user = self.request.iser
        queryset = CustomerUserViceInviterRecord.objects.filter(qrcode__user=user.id).order_by('-create_time')
        qrcode_id = self.request.query_params.get('qrcode_id', None)
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        if qrcode_id:
            self.request.data['inviter_count'] = str(queryset.filter(is_inviter=1, qrcode_id=qrcode_id).count())
        return queryset

    def get_serializer_class(self):
        return CustomerUserViceInviterRecordListModelSerializer


class NewYearsShoppingFestivalElectModelViewSet(ModelViewSet):

    pagination_class = MyPage
    queryset = NewYearsShoppingFestivalElect.objects.exclude(activity_state=0).order_by('-id')
    serializer_class = NewYearsShoppingFestivalElectListModelSerializer

    def get_serializer_context(self):
        user = self.request.iser
        return {'user': user}


class NewYearsShoppingFestivalElectProductModelViewSet(ModelViewSet):

    pagination_class = MyPage

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        elect_id = self.request.query_params.get('elect_id', 1)
        # if level.level == 0:
        #     queryset = NewYearsShoppingFestivalElectProduct.objects.all()
        # elif level.level == 1:
        #     queryset = NewYearsShoppingFestivalElectProduct.objects.filter(level__prov_id=level.id)
        # elif level.level == 2:
        #     queryset = NewYearsShoppingFestivalElectProduct.objects.filter(level__city_id=level.id)
        # elif level.level == 3:
        #     queryset = NewYearsShoppingFestivalElectProduct.objects.filter(level__district_id=level.id)
        # else:
        #     queryset = NewYearsShoppingFestivalElectProduct.objects.filter(level__branch_id=level.id)
        if self.action == 'list':
            if elect_id:
                queryset = NewYearsShoppingFestivalElectProduct.objects.exclude(is_match=1).filter(level_id=level.id)
            else:
                queryset = NewYearsShoppingFestivalElectProduct.objects.filter(elect_id=elect_id, level_id=level.id).exclude(is_match=1)
        else:
            queryset = NewYearsShoppingFestivalElectProduct.objects.all()
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        match_product = NewYearsShoppingFestivalElectProduct.objects.filter(is_match=1, level_id=level.id).first()
        self.request.data['match_product'] = NewYearsShoppingFestivalElectProductListModelSerializer(match_product).data
        return queryset.order_by('-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return NewYearsShoppingFestivalElectProductListModelSerializer
        else:
            return NewYearsShoppingFestivalElectProductRetrieveModelSerializer

    def get_serializer_context(self):
        user = self.request.iser
        return {'user': user}

    def product_pic(self, request):
        user = self.request.iser
        img = self.request.FILES.get('img', None)
        if not img:
            return Response({'error': '请上传图片'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            mid_img = pic_upload(img_str, key=None)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'success': '操作成功', 'img_id': f'https://circle.sutpay.cn/{mid_img}'}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        product_title = self.request.data.get('product_title', None)
        product_intro = self.request.data.get('product_intro', None)
        image_set = self.request.data.get('image_set', None)
        elect_id = self.request.data.get('elect_id', 1)
        if not elect_id:
            return Response({'error': '请上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            elect = NewYearsShoppingFestivalElect.objects.get(id=elect_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if elect.available_end_time <= datetime.datetime.now():
            return Response({'error': '活动已结束,不可创建作品'}, status=status.HTTP_400_BAD_REQUEST)
        check_product = NewYearsShoppingFestivalElectProduct.objects.filter(manageruser_id=user.id, elect_id=elect_id)
        if check_product:
            return Response({'error': '每个客户经理只能创建一个作品'}, status=status.HTTP_400_BAD_REQUEST)
        if not product_title:
            return Response({'error': '请上传作品标题'}, status=status.HTTP_400_BAD_REQUEST)
        if not product_intro:
            return Response({'error': '请上传作品简介'}, status=status.HTTP_400_BAD_REQUEST)
        if not image_set:
            return Response({'error': '请上传作品图片'}, status=status.HTTP_400_BAD_REQUEST)
        if type(image_set) != list:
            return Response({'error': '图片参数个数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if len(image_set) > 5:
            return Response({'error': '最大只能上传5张图片'}, status=status.HTTP_400_BAD_REQUEST)
        level = user.level
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                product_data = {}
                product_data['elect_id'] = elect_id
                product_data['product_title'] = product_title
                product_data['product_intro'] = product_intro
                product_data['longitude'] = level.longitude
                product_data['latitude'] = level.latitude
                product_data['manageruser_id'] = user.id
                product_data['level_id'] = level.id
                product_data['default_image'] = image_set[0].replace("https://circle.sutpay.cn/", "")
                product, create = NewYearsShoppingFestivalElectProduct.objects.get_or_create(defaults=product_data, elect_id=elect_id, manageruser_id=user.id)
                if create:
                    for image in image_set:
                        image_data = {}
                        image_data['product_id'] = product.id
                        image_data['image'] = image.replace("https://circle.sutpay.cn/", "")
                        NewYearsShoppingFestivalElectProductPic.objects.create(**image_data)
                transaction.savepoint_commit(save_id)
                check_product_march = NewYearsShoppingFestivalElectProduct.objects.filter(level_id=level.id, is_match=1)
                level_admin = User.objects.filter(level_id=level.id, role_id=2).first()
                if level_admin:
                    if check_product_march:
                        msg = f'当前已有参赛作品，如需替换参赛作品，请联系【机构管理员】（{level_admin.mobile}）进行替换操作。'
                    else:
                        product.is_match = 1
                        product.save()
                        msg = f'当前作品为本机构第一个作品，将会默认成为参赛作品，如需替换，请联系【机构管理员】（{level_admin.mobile}）进行替换操作。'
                else:
                    if check_product_march:
                        msg = f'当前已有参赛作品，如需替换参赛作品，请联系【机构管理员】进行替换操作。'
                    else:
                        product.is_match = 1
                        product.save()
                        msg = f'当前作品为本机构第一个作品，将会默认成为参赛作品，如需替换，请联系【机构管理员】进行替换操作。'
                return Response({'success': msg}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '创建作品失败,请联系客服处理'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        if instance.manageruser_id != user.id:
            return Response({'error': '你无权限修改当前作品'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.elect.available_begin_time <= datetime.datetime.now():
            return Response({'error': '比赛已经开始,不可中途修改作品信息'}, status=status.HTTP_400_BAD_REQUEST)
        product_title = self.request.data.get('product_title', None)
        product_intro = self.request.data.get('product_intro', None)
        image_set = self.request.data.get('image_set', None)
        if product_title:
            instance.product_title = product_title
        if product_intro:
            instance.product_intro = product_intro
        if image_set:
            if type(image_set) != list:
                return Response({'error': '图片参数个数有误'}, status=status.HTTP_400_BAD_REQUEST)
            if len(image_set) > 5:
                return Response({'error': '最大只能上传5张图片'}, status=status.HTTP_400_BAD_REQUEST)
            new_image_set = []
            for image in image_set:
                new_image_set.append(image.replace('https://circle.sutpay.cn/', ''))
            instance.default_image = new_image_set[0]
            old_image_set = NewYearsShoppingFestivalElectProductPic.objects.filter(product_id=instance.id)
            for old_image in old_image_set:
                if old_image.image.name not in new_image_set:
                    old_image.delete()
            for image in new_image_set:
                image_data = {}
                image_data['product_id'] = instance.id
                image_data['image'] = image
                NewYearsShoppingFestivalElectProductPic.objects.get_or_create(defaults=image_data, product_id=instance.id, image=image)
        instance.save()
        return Response({'success': '修改成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        if instance.elect.available_begin_time <= datetime.datetime.now():
            return Response({'error': '比赛已经开始,不可中途替换参赛作品'}, status=status.HTTP_400_BAD_REQUEST)
        if user.role_id == 3:
            return Response({'error': '您无权限发布作品'}, status=status.HTTP_400_BAD_REQUEST)
        if user.level_id != instance.level_id:
            return Response({'error': '您无权限发布作品'}, status=status.HTTP_400_BAD_REQUEST)
        NewYearsShoppingFestivalElectProduct.objects.filter(level_id=user.level_id, is_match=1).update(is_match=0)
        instance.is_match = 1
        instance.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def leaderboard(self, request):
        user = self.request.iser
        elect_id = self.request.query_params.get('elect_id', 1)
        level = user.level
        queryset = NewYearsShoppingFestivalElectProduct.objects.filter(is_match=1, elect_id=elect_id).order_by('-like_count', 'id')[:10]
        index = 1
        product_lists = []
        check_level = 1
        response_data = {}
        for query in queryset:
            if query.level_id == level.id:
                check_level = 0
            data = NewYearsShoppingFestivalElectProductListModelSerializer(query).data
            data['index'] = index
            product_lists.append(data)
            index += 1
        response_data['product_lists'] = product_lists
        if check_level:
            product = NewYearsShoppingFestivalElectProduct.objects.filter(level_id=level.id, is_match=1).first()
            response_data['product'] = NewYearsShoppingFestivalElectProductRetrieveModelSerializer(product).data
        else:
            response_data['product'] = ''
        return Response(response_data, status=status.HTTP_200_OK)


class GoodsCommentModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'goods__name')
    filter_class = OrderGoodsFilter
    serializer_class = GoodsCommentModelSerializer

    def get_queryset(self):
        user = self.request.iser
        queryset = OrderGoods.objects.filter(is_commented=1).order_by('-id')
        return queryset


class GoodsTagActivityLevelRelationModelViewSet(ModelViewSet):

    # pagination_class = MyPage
    # filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    # search_fields = ('goods_tag_activity__activity_state', 'goods__name')
    # filter_class = OrderGoodsFilter
    serializer_class = GoodsTagActivityLevelRelationModelSerializer

    def get_queryset(self):
        search = self.request.query_params.get('search', None)
        user = self.request.iser
        queryset = GoodsTagActivityLevelRelation.objects.filter(goods_tag_activity__activity_state=1, level_id=user.level_id).distinct()
        if search:
            goods_tag_list = AliDiscountCoupon.objects.filter(Q(activity_name__contains=search) | Q(template_id__contains=search)).filter(goods_tag__isnull=False).values_list('goods_tag', flat=True)
            queryset = queryset.filter(Q(goods_tag_activity__goods_tag__in=goods_tag_list) | Q(goods_tag_activity__goods_tag__contains=search))
        return queryset

    def get_serializer_context(self):
        user = self.request.iser
        return {'user': user}
